简体   繁体   中英

How to get generated keys by executeBatch without ArrayIndexOutOfBoundsException?

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.

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 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM