如何在一条语句中将多行插入 DB2?
Posted
技术标签:
【中文标题】如何在一条语句中将多行插入 DB2?【英文标题】:How do I insert multilple rows into a DB2 in one statement? 【发布时间】:2018-09-17 19:58:10 【问题描述】:我正在使用 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 中的对象并延长插入语句,直到它包含 ArrayList 中的所有行。然后,当循环完成时,我清理字符串的末尾,并尝试执行该语句。
下面是执行方法时查询语句的样例:
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,错误标记 = ,;FOR NOT ATOMIC ERRORCODE=-104,SQLSTATE=42601
我的错误标记是一个逗号,我不确定它指的是哪个。有没有办法在 DB2 表中插入多行?帮助将不胜感激!
【问题讨论】:
你认为你的最终陈述会是这样吗,还是你真的把它打印出来了?您是否尝试从日志中复制它并在其中执行它,比如 Db2 CLP?您不使用参数化语句的任何原因? 是的,这不是标准 SQL。 Microsoft SQL Server 支持这一点,但我相当肯定 DB2 不支持。您必须发出多个 INSERT 语句。 是的。该声明来自系统输出 一次一个。感谢您的输入。对这些东西很陌生。只是试图验证我不是简单地输入错误或误解了逻辑 我使用的是 DB2 版本 12 【参考方案1】:您可以改用批处理语句:
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();
【讨论】:
这是一个有效的方法。非常感谢,也感谢关于嵌入的建议。我是在我的环境类型中编写程序的新手,所以我仍在学习如何以更安全的方式编写程序。我会在此基础上进行调整。【参考方案2】:您似乎正在为 z/OS 使用“JDBC 和 SQLJ 类型 2 连接驱动程序”,因此我假设您的 Db2 服务器在 z/OS 上运行。
Db2 for z/OS 支持 jdbc、静态 SQL 和动态 SQL 的多行插入,如果有很多行要频繁插入,那么使用多行插入是明智的。它使用了与您的问题中显示的不同的方法(即不使用您尝试的 VALUES 子句)。
驱动程序属性enableMultiRowInsertSupport
可用,应默认启用。如果您希望多行插入是原子的,请注意驱动程序属性atomicMultiRowInsert
。
研究 jdbc 示例(在末尾)this page。有关驱动程序设置的详细信息,请参阅 Db2 知识中心。
【讨论】:
以上是关于如何在一条语句中将多行插入 DB2?的主要内容,如果未能解决你的问题,请参考以下文章
如何制作将生成 SQL 以在一条语句中插入多个值的 HQL?