Java预处理语句获取生成的键在DB2中不起作用,但在mySQL中起作用?

mdfafbf1  于 2022-11-07  发布在  DB2
关注(0)|答案(2)|浏览(196)

我有一个非常简单的表,在MySQL和DB2中都有,名为STUDENTID(主键,自动递增)、FIRST_NAMELAST_NAMEAGE
表在两个数据库中被复制,因此它们在语法上应该是相同的。但是,我花了一整天的时间试图弄清楚为什么当我编写一个简单的Java程序插入数据库时,MySQL版本通过PreparedStatement.getGeneratedKeys()返回生成的键,而DB2版本不返回任何东西。
我的代码如下所示:

  1. String sql = "INSERT INTO STUDENT (FIRST_NAME, LAST_NAME, AGE) VALUES ('Jacob', 'Eldy', 19)"
  2. final Connection connection = getConnection(dataSource.get());
  3. int[] insertedRows = null;
  4. ResultSet rs = null;
  5. PreparedStatement ps = null;
  6. try {
  7. ps = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
  8. ps.addBatch();
  9. insertedRows = ps.executeBatch();
  10. rs = ps.getGeneratedKeys();
  11. while(rs.next()) {
  12. LOGGER.info(rs.getString(1));
  13. }
  14. connection.commit();
  15. } catch (Exception e) {
  16. try {
  17. connection.rollback();
  18. } catch (SQLException e) {
  19. e.printStackTrace();
  20. }
  21. } finally {
  22. close(ps, connection);
  23. }

在提交DB2和MySQL数据库的连接后,实际上都显示了插入的行,插入的行越多,就会出现一个新行,并带有自动递增的ID,但是只有MySQL数据库的值为while(rs.next()),DB2版本跳过了它,因为它是空的。
我做错了什么吗?这只是一个与DB2的不兼容问题,它只是不返回生成的值吗?如果是这样,解决这个问题的最佳解决方案是什么?
UPDATE,添加用于DB2和mySQL的两个DDL:
mySQL数据描述语言:

  1. CREATE TABLE 'STUDENT'
  2. ...
  3. `ID` int NOT NULL AUTO_INCREMENT
  4. PRIMARY KEY('ID')
  5. AUTO_INCREMENT=19073

DB2数据库描述语言:

  1. CREATE TABLE STUDENT
  2. (
  3. ID INTEGER DEFAULT IDENTITY GENERATED ALWAYS NOT NULL
  4. PRIMARY KEY (ID)
  5. )
xmq68pz9

xmq68pz91#

  1. CREATE TABLE STUDENT
  2. (
  3. ID INT NOT NULL GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY
  4. , FIRST_NAME VARCHAR (20)
  5. , LAST_NAME VARCHAR (20)
  6. , AGE SMALLINT
  7. );

以下代码基于其他人提供的Making batch updates in JDBC applications链接(此链接用于Db2 for LUW),可与上述表定义一起正常工作:

  1. PreparedStatement ps = con.prepareStatement
  2. (
  3. "INSERT INTO STUDENT (FIRST_NAME, LAST_NAME, AGE) " +
  4. "VALUES (?,?,?)"
  5. , Statement.RETURN_GENERATED_KEYS
  6. );
  7. ps.setString (1, "Jacob");
  8. ps.setString (2, "Eldy");
  9. ps.setShort (3, (short) 19);
  10. ps.addBatch();
  11. ps.setString (1, "Jacob");
  12. ps.setString (2, "Eldy");
  13. ps.setShort (3, (short) 19);
  14. ps.addBatch();
  15. int [] numUpdates = ps.executeBatch();
  16. for (int i=0; i < numUpdates.length; i++)
  17. if (numUpdates[i] == Statement.SUCCESS_NO_INFO)
  18. System.out.println("Execution " + i + ": unknown number of rows updated");
  19. else
  20. System.out.println("Execution " + i + " successful: " + numUpdates[i] + " rows updated");
  21. ResultSet[] resultList = ((com.ibm.db2.jcc.DB2PreparedStatement) ps).getDBGeneratedKeys();
  22. if (resultList.length != 0)
  23. for (int i = 0; i < resultList.length; i++)
  24. {
  25. while (resultList[i].next())
  26. System.out.println("Automatically generated key value = " + resultList[i].getBigDecimal(1));
  27. resultList[i].close();
  28. }
  29. else
  30. System.out.println("Error retrieving automatically generated keys");
展开查看全部
dtcbnfnu

dtcbnfnu2#

我做错了什么吗?这只是一个与DB2的不兼容问题,它只是不返回生成的值吗?如果是这样,解决这个问题的最佳解决方案是什么?
是的,你做错了。这不是不兼容的问题,也不是一个问题。DB2不同于MySQL。你不能同时处理这两个,因为你有不兼容的DDL。因为没有记录插入DB2,所以键的值不可用。
此问题的解决方案是在插入记录时创建一个触发器,以确保将主键插入到数据库中。如果缺少一个键,则从序列中选择它并替换值。
现在,如果像这样将标识生成到DB2中

  1. CREATE TABLE STUDENT
  2. (
  3. ID INTEGER DEFAULT IDENTITY GENERATED ALWAYS NOT NULL
  4. PRIMARY KEY (ID)
  5. )

因此,它将始终返回getGeneratedKeys()

相关问题