How to get generated keys by executeBatch without ArrayIndexOutOfBoundsException?

我们两清 提交于 2019-12-01 06:34:53

问题


The following method I want to INSERT several records simultaneously.

public void insert() {
    try {
        this.connection.setAutoCommit(false);
        PreparedStatement ps = this.connection.prepareStatement(
                "INSERT INTO  COMPANY (NAME,Address) Values (?,?)", new String[]{"ID"});
        ps.setString(1, "X01");
        ps.setString(2, "Address1");
        ps.addBatch();

        ps.setString(1, "Y01");
        ps.setString(2, "Address2");
        ps.addBatch();

       //EXCEPTION OCCURS HERE
        int[] numUpdates = ps.executeBatch();

        for (int i = 0; i < numUpdates.length; i++) {
                System.out.println("Execution " + i +
                        "successful: " + numUpdates[i] + " rows inserted");
        }

        ResultSet resultSet =
                (ps).getGeneratedKeys();
        while (resultSet.next()) {
            String deptNoKey = resultSet.getString(1);
            System.out.println("Automatically generated key value = "
                    + deptNoKey);
        }
    } catch (BatchUpdateException b) {
        // process BatchUpdateException
    } catch (SQLException e) {
        e.printStackTrace();
    }

}

At this point, when I expect to get the PK's generated for each INSERT, I get this Exception

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 22
  at oracle.jdbc.driver.T4CNumberAccessor.unmarshalOneRow(T4CNumberAccessor.java:250)
  at oracle.jdbc.driver.T4C8Oall.receive(T4C8Oall.java:754)
  at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:216)
  at oracle.jdbc.driver.T4CPreparedStatement.executeForRows(T4CPreparedStatement.java:1250)
  at oracle.jdbc.driver.OraclePreparedStatement.executeForRowsWithTimeout(OraclePreparedStatement.java:14264)
  at oracle.jdbc.driver.OraclePreparedStatement.executeBatch(OraclePreparedStatement.java:14379)
  at oracle.jdbc.driver.OracleStatementWrapper.executeBatch(OracleStatementWrapper.java:589)
  at dbpro.SqlHelper.insert2(SqlHelper.java:988)
  at dbpro.SqlHelper.main(SqlHelper.java:1023)
  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  at java.lang.reflect.Method.invoke(Method.java:483)
  at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)

After Exception: In The table COMPANY , two records are added correctly but I expected to get a ResultSet with one row for each insert performed, so I could get each PK generated.


回答1:


This appears to be a bug in Oracle on Windows, the driver JAR ojdbc6.jar, or (knowing Oracle) both.

There's no significant problem with the code you have presented. It should work, although when I ran it the numbers of rows inserted each time was returned as -2 (= Statement.SUCCESS_NO_INFO), so you may be better off ignoring these numbers.

Your code runs fine for me with Oracle 11g XE 11.2.0.2.0 on Linux with four versions of the Oracle JDBC driver JAR. However, if I run it on Windows 10 with the same version of Oracle XE and with ojdbc6.jar, it fails with the same ArrayIndexOutOfBoundsException you are getting. The problem goes away if I use ojdbc7.jar instead of ojdbc6.jar.

Therefore, I would recommend replacing ojdbc6.jar with ojdbc7.jar, which you can download from here.



来源:https://stackoverflow.com/questions/33593452/how-to-get-generated-keys-by-executebatch-without-arrayindexoutofboundsexception

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!