我正在使用Java和jdbc驱动程序来建立到DB2数据库的连接。我试图使用一条语句将多个行插入表中。
下面是我的代码:
public void createResources(List<Resources> addedResources)
throws SQLException{
Connection conn = null;
PreparedStatement statement = null;
int i = 0;
String values = "INSERT INTO GROUPS (GROUP_NAME, ENTRY_NAME,
ENTRY_TYPE, LAST_REQ, CREATE_BY, REQ_BY, LAST_CHANGED, LAST_REQ_TIME) VALUES
" + System.getProperty("line.separator");
while(i < addedResources.size()){
Timestamp LAST_CHANGED =
Timestamp.valueOf(addedResources.get(i).getLAST_CHANGED().trim());
Timestamp LAST_REQ_TIME =
Timestamp.valueOf(addedResources.get(i).getLAST_REQ_TIME().trim());
values = values + "('" +
addedResources.get(i).getGROUP_NAME().trim() + "', '" +
addedResources.get(i).getENTRY_NAME().trim() + "', '" +
addedResources.get(i).getENTRY_TYPE().trim() + "', '" +
addedResources.get(i).getLAST_REQ().trim() + "', '" +
addedResources.get(i).getCREATE_BY().trim() + "', '" +
addedResources.get(i).getREQ_BY().trim() + "', '" +
LAST_CHANGED + "', '" +
LAST_REQ_TIME + "')," +
System.getProperty("line.separator");
i = i + 1;
}
values = values.substring(0,values.trim().length()-1);
Log(Integer.toString(values.length()));
Log(values);
try {
// Get the DB connection
conn = this.ds.getConnection();
conn.setAutoCommit(false);
// Prepare the statement and populate with data
statement = conn.prepareStatement(values);
// Perform the INSERT operation
statement.executeUpdate();
//Commit the changes
conn.commit();
Log("Employee Successfully Added!");
}
finally{
// Any exceptions will be propagated
// Close database objects, regardless of what happened
if ( statement != null ) {
statement.close();
}
if ( conn != null ) {
conn.close();
}
}
}
总而言之,我有一个循环,循环遍历List中的对象,并拉长insert语句,直到它包含ArrayList中的所有行。然后,我在循环完成后清理String的结尾,并尝试执行该语句。
以下是执行该方法时查询语句的外观示例:
INSERT INTO GROUPS (GROUP_NAME, ENTRY_NAME, ENTRY_TYPE, LAST_REQ, CREATE_BY,
REQ_BY, LAST_CHANGED, LAST_REQ_TIME) VALUES
('JOHN', 'TEST1', 'FILE', 'N/A', 'SSDP071', 'N/A', '2018-09-17
19:36:34.004', '2018-09-17 19:36:34.004'),
('JOHN', 'TEST2', 'FILE', 'N/A', 'SSDP071', 'N/A', '2018-09-17
19:36:37.771', '2018-09-17 19:36:37.771'),
('JOHN', 'TEST3', 'FILE', 'N/A', 'SSDP071', 'N/A', '2018-09-17
19:36:42.021', '2018-09-17 19:36:42.021')
我的代码尝试执行并引发以下错误:
[9/17/18 19:36:42:834 GMT] 00000557 SystemOut O com.ibm.db2.jcc.am.SqlSyntaxErrorException:[jcc] [50053] [12311] [4.22.37] T2zOS异常: [jcc] [T2zos] T2zosPreparedStatement.readPrepareDescribeOutput_:nativePrepareInto:1583:DB2引擎SQL错误,SQLCODE = -104,SQLSTATE = 42601,错误令牌= ;;对于非原子错误代码= -104,SQLSTATE = 42601
我的错误令牌是逗号,我不确定它所指的是什么。没有办法在DB2表中插入多行吗?帮助将不胜感激!
答案 0 :(得分:0)
对于z / OS,您似乎正在使用“用于JDBC和SQLJ type 2连接的驱动程序”,因此,我假设您的Db2服务器在z / OS上运行。
用于z / OS的Db2支持jdbc,静态SQL和动态SQL的多行插入,如果要频繁插入很多行,那么使用多行插入是明智的。它使用的方法与问题中显示的方法不同(即您尝试时不使用VALUES子句)。
驱动程序属性enableMultiRowInsertSupport
可用,应默认为启用。如果您希望多行插入是原子的,请注意驱动程序属性atomicMultiRowInsert
。
研究this page的jdbc示例。有关驱动程序设置的详细信息,请参阅Db2知识中心。
答案 1 :(得分:0)
您可以改用批处理语句:
String values = "INSERT INTO GROUPS " +
"(GROUP_NAME,ENTRY_NAME,ENTRY_TYPE,LAST_REQ,CREATE_BY,REQ_BY,LAST_CHANGED,LAST_REQ_TIME) " +
"VALUES (?,?,?,?,?,?,?,?)";
// ...
statement = conn.prepareStatement(values);
// ...
while(i < addedResources.size()){
statement.setString(addedResources.get(i)).getGROUP_NAME().trim());
statement.setString(addedResources.get(i)).getENTRY_NAME().trim());
// ...
statement.addBatch();
}
statement.executeBatch();