如何在 hsql 中为另一个架构所有者创建表
Posted
技术标签:
【中文标题】如何在 hsql 中为另一个架构所有者创建表【英文标题】:how can I create a table for another schema owner in hsql 【发布时间】:2017-10-18 21:58:29 【问题描述】:我正在为 Spring 批处理应用程序编写测试用例。我需要设置一个镜像远程大型机 db2 数据库的 HSQL 数据库,以便我可以快速运行我的测试。
我必须设置 db 表以使以下 SQL 语句成功:
SELECT PROJ_TYP, SYS_CD, ... FROM CMNREF.CNTRCT_EXTRNL_KEY_REF_V WITH UR
我相信上面的 CMNREF 是 Schema 所有者。如何在 HSQL db 中创建该表和架构,以便此 SELECT 可以工作?
更新: 对主题here 进行了一些研究,我了解到我需要执行以下操作: 1)使用SA默认用户创建新用户CMNREF 2) 授予用户 CMNREF 一些 ROLES(即 SELECT)
但是,我也注意到默认用户 SA 具有 DBA 角色,这意味着它可以在该数据库上执行任何操作....所以我想知道我是否需要费心创建上面的 1 和 2... .
我的测试用例:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "/load-BMS-data-job-launcher-context.xml" )
public class SimpleJobLaunchFunctionalTests
@Autowired
private JobLauncherTestUtils jobLauncherUtils;
@Qualifier("jdbcTemplate")
@Autowired
private JdbcOperations jdbcTemplate;
@Qualifier("jdbcTemplateBMS")
@Autowired
private JdbcOperations jdbcTemplateBMS;
@Before
public void setUp()
jdbcTemplateBMS.update("DELETE from CMNREF.CNTRCT_EXTRNL_KEY_REF_V");
jdbcTemplate.update("DELETE from SHADOW_BMS");
// jdbcTemplate.update("DELETE from CMNREF.CNTRCT_EXTRNL_KEY_REF_V");
Calendar calendar = Calendar.getInstance();
java.sql.Timestamp currentTimestamp = new java.sql.Timestamp(calendar.getTime().getTime());
// Insert one test data record
jdbcTemplate.update("INSERT INTO CMNREF.CNTRCT_EXTRNL_KEY_REF_V(PROJ_TYP_CD, SYS_CD, STAT_CK_CD, EXTRNL_KEY_CD, EXTRNL_SYS_CD, CNTRCT_NUM, PROJ_NUM, CNTRCT_LINE_ITM, CUST_NUM, CUST_CNTL_NUM, CUST_NM, CHRG_CD, PRDCT_ID, BILNG_CRNCY_CD, BILNG_ISO_CRNCY_CD, BILNG_CRNCY_DCM_NUM, CFTS_CRNCY_EXCH_RT, CFTS_CRNCY_EXCH_RT_EXPIR_DT, CHRG_CRNCY_CD, CHRG_ISO_CRNCY_CD, CTRY_CD, CMPNY_CD, OFFERING_CD, CNTL_GRP_CD, ORIG_CTRY_CD, ORIG_CMPNY_CD, ORIG_LOC_CD, NOTES_ID, INET_ID, CFTS_GBI_IND, CFTS_CHRG_TYP_CD, CFTS_SPCL_HNDL_CD, CC_PMT_METH_IND, STAT_CD, REFRESH_TMS) VALUES('PROJT1', 'SCD', 'STC', 'EXTKEY','EXTSYSCODE', 'CTR923','PROJN293', 23, 'CNUM32', 'CN', 'NAME THIS CUST', 'CHCD', '2903-920','BCD', 'BIC', 23, 1.345, '2017-01-23','CCC', 'CIC', 'CCD', 'IBM', '9203L-98', 'CTLGRP', 'USA', 'IBM001', 'OLC', 'me@us.ibm.com', 'ME/US/IBM/COM', 'G', 'T', 'H', 'P', 'OPEN', '2016-01-02 19:29:23.271' )");
我的数据库脚本在那里:
CREATE USER CMNREF PASSWORD 'pw';
CREATE SCHEMA CMNREF AUTHORIZATION DBA;
ALTER USER CMNREF SET INITIAL SCHEMA CMNREF;
SET SCHEMA CMNREF;
CREATE TABLE CMNREF.CNTRCT_EXTRNL_KEY_REF_V (
PROJ_TYP_CD VARCHAR(10),
SYS_CD VARCHAR(3),
STAT_CK_CD VARCHAR(12),
EXTRNL_KEY_CD VARCHAR(36),
EXTRNL_SYS_CD VARCHAR(10),
CNTRCT_NUM VARCHAR(15),
PROJ_NUM VARCHAR(8),
CNTRCT_LINE_ITM INTEGER,
CUST_NUM VARCHAR(8),
CUST_CNTL_NUM VARCHAR(2),
CUST_NM VARCHAR(35),
CHRG_CD VARCHAR(4),
PRDCT_ID VARCHAR(15),
BILNG_CRNCY_CD VARCHAR(3),
BILNG_ISO_CRNCY_CD VARCHAR(3),
BILNG_CRNCY_DCM_NUM SMALLINT,
CFTS_CRNCY_EXCH_RT DECIMAL,
CFTS_CRNCY_EXCH_RT_EXPIR_DT DATE,
CHRG_CRNCY_CD VARCHAR(3),
CHRG_ISO_CRNCY_CD VARCHAR(3),
CTRY_CD VARCHAR(3),
CMPNY_CD VARCHAR(10),
OFFERING_CD VARCHAR(8),
CNTL_GRP_CD VARCHAR(8),
ORIG_CTRY_CD VARCHAR(3),
ORIG_CMPNY_CD VARCHAR(10),
ORIG_LOC_CD VARCHAR(3),
NOTES_ID VARCHAR(100),
INET_ID VARCHAR(100),
CFTS_GBI_IND VARCHAR(1),
CFTS_CHRG_TYP_CD VARCHAR(1),
CFTS_SPCL_HNDL_CD VARCHAR(1),
CC_PMT_METH_IND VARCHAR(1),
STAT_CD VARCHAR(12),
REFRESH_TMS TIMESTAMP
) ;
我的数据源在这里定义:
<!-- Initialise the database before every test case: -->
<jdbc:initialize-database data-source="dataSource">
<jdbc:script location="$batch.drop.script"/>
<jdbc:script location="$batch.schema.script"/>
<jdbc:script location="$batch.business.schema.script"/>
</jdbc:initialize-database>
<!-- Initialize the mock BMS database -->
<jdbc:initialize-database data-source="BMSdataSource" ignore-failures="DROPS">
<jdbc:script location="$bmsmock.business.schema.script"/>
</jdbc:initialize-database>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="$batch.jdbc.driver" />
<property name="url" value="$batch.jdbc.url" />
<property name="username" value="$batch.jdbc.user" />
<property name="password" value="$batch.jdbc.password" />
<property name="maxActive" value="$batch.jdbc.pool.size"/>
<property name="validationQuery" value="$batch.jdbc.validationQuery"/>
<property name="testWhileIdle" value="$batch.jdbc.testWhileIdle"/>
</bean>
<bean id="BMSdataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="$bmsmock.jdbc.driver" />
<property name="url" value="$bmsmock.jdbc.url" />
<property name="username" value="$bmsmock.jdbc.user" />
<property name="password" value="$bmsmock.jdbc.password" />
<property name="maxActive" value="$bmsmock.jdbc.pool.size"/>
<property name="validationQuery" value="$bmsmock.jdbc.validationQuery"/>
<property name="testWhileIdle" value="$bmsmock.jdbc.testWhileIdle"/>
</bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" lazy-init="true">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- Set up or detect a System property called "ENVIRONMENT" used to construct a properties file on the classpath. The default is "hsql". -->
<bean id="environment"
class="org.springframework.batch.support.SystemPropertyInitializer">
<property name="defaultValue" value="hsql"/>
<property name="keyName" value="ENVIRONMENT"/>
</bean>
<bean id="placeholderProperties" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
depends-on="environment">
<property name="location" value="classpath:batch-$ENVIRONMENT.properties" />
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
<property name="ignoreUnresolvablePlaceholders" value="true" />
<property name="order" value="1" />
</bean>
My HSQLDB Properties are below:
batch.jdbc.driver=org.hsqldb.jdbcDriver
batch.jdbc.url=jdbc:hsqldb:mem:testdb;sql.enforce_strict_size=true;hsqldb.tx=mvcc
batch.jdbc.user=sa
batch.jdbc.password=
batch.jdbc.testWhileIdle=false
batch.jdbc.validationQuery=
batch.drop.script=classpath:/org/springframework/batch/core/schema-drop-hsqldb.sql
batch.schema.script=classpath:/org/springframework/batch/core/schema-hsqldb.sql
batch.business.schema.script=classpath:/db/custom-db-assets.sql
batch.database.incrementer.class=org.springframework.jdbc.support.incrementer.HsqlMaxValueIncrementer
batch.database.incrementer.parent=columnIncrementerParent
batch.lob.handler.class=org.springframework.jdbc.support.lob.DefaultLobHandler
batch.jdbc.pool.size=6
batch.grid.size=6
batch.verify.cursor.position=true
batch.isolationlevel=ISOLATION_SERIALIZABLE
batch.data.source.init=true
batch.table.prefix=BATCH_
bmsmock.jdbc.driver=org.hsqldb.jdbcDriver
bmsmock.jdbc.url=jdbc:hsqldb:mem:testbms;sql.enforce_strict_size=true;hsqldb.tx=mvcc
bmsmock.jdbc.user=SA
bmsmock.jdbc.password=
bmsmock.jdbc.pool.size=6
bmsmock.jdbc.testWhileIdle=false
bmsmock.jdbc.validationQuery=
bmsmock.business.schema.script=db/mock-bms-tables.sql
【问题讨论】:
上面的一些研究...... 【参考方案1】:使用没有 DBA 角色的其他用户是个好主意。
在 HSQLDB 中,用户和模式是独立的概念,每个用户没有自动模式。你所做的很好。或者你可以
CREATE USER CMNREF PASSWORD 'pw'
CREATE SCHEMA CMNREF AUTHORIZATION CMNREF
通过上述内容,CMNREF 用户拥有同名的架构。它可以执行自己架构中的所有语句。
更新:在您的设置中,SA 用户用于所有操作。您需要使用用户 SA 运行您引用的 DB 脚本的用户创建部分,然后使用用户 CMNREF 运行测试。
【讨论】:
org.springframework.jdbc.BadSqlGrammarException: StatementCallback;错误的 SQL 语法 [INSERT INTO CNTRCT_EXTRNL_KEY_REF_V(PROJ_TYP_CD...'ME/US/IBM/COM', 'G', 'T', 'H', 'P', 'OPEN', '2016-01-02 19: 29:23.271')];嵌套异常是 java.sql.SQLSyntaxErrorException: 用户缺少权限或找不到对象: CNTRCT_EXTRNL_KEY_REF_V 我已经像这样启动了 HSQL 管理器: java -cp hsqldb.jar org.hsqldb.util.DatabaseManagerSwing 我可以在那里运行所有命令,我可以插入和选择数据......为什么不在 SpringJdbcTemplate 中? 在 DBManager 和 Spring 中使用完全相同的连接 URL 以获得相同的行为。 我做了……完全一样……这就是令人沮丧的地方。我不知道有什么不同。我看到的唯一神秘的是,我正在调用的 SQL 是这样的:“INSERT INTO CMNREF.CNTRCT_EXTRNL_KEY_REF_V(PROJ_TYP_...)”并且错误显示为:用户缺少特权或找不到对象:CNTRCT_EXTRNL_KEY_REF_V,没有架构预选赛?! 还有 INITIAL SCHEMA 的概念,由两个 SET .. INITIAL SCHEMA 语句支持,CURRENT_SCHEMA 可以通过 SET SCHEMA 语句来改变。【参考方案2】:我的脚本(附件)显示了如何做到这一点。没错,脚本或架构定义没有错。我的问题是我的测试用例在将数据插入 CMNREF.C* 表时引用了错误的 Jdbc 模板....正确的 stmt 应该是:
jdbcTemplateBMS**.update("INSERT INTO CMNREF.CNTRCT_E
另外,我需要打开 DB2 模式才能让我的 sql 脚本正常工作
【讨论】:
以上是关于如何在 hsql 中为另一个架构所有者创建表的主要内容,如果未能解决你的问题,请参考以下文章