ORACLE JDBC 批处理执行没有 return 受影响行的实际计数

ORACLE JDBC Batch execution doesn't return actual count of affected rows

我正在开发一个使用 JDBCOracle11.

的应用程序

我的 table tbltest 中有数十万条记录,我正在通过 JDBC 批量执行进行更新。所以将其视为 one id = one query.

我的要求: 我想跟踪哪些 id 已成功更新,哪些不存在于数据库中。

以下是我的代码:

String sql = "UPDATE TBLTEST SET STATUS = 'CANCEL' WHERE ID = ?";
PreparedStatement preparedStatement = null;
Connection connection = getConnection(); // I'm getting this connection properly
preparedStatement = connection.prepareStatement(sql);

for (String id : idList) { // idList is a List of String being passed to my method
    preparedStatement.setString(1, id);
    preparedStatement.addBatch();
}
int[] affectedRecords = preparedStatement.executeBatch();

System.out.println("Records affected:"+Arrays.toString(affectedRecords));
int success = preparedStatement.getUpdateCount();
System.out.println(success + " Total updated");

我的记录已根据提供的 idList 成功更新。根据 this Javadoc,在 affectedRecords 中,我应该得到实际编号。每个更新查询更新的记录数,因为我没有收到任何异常。 相反,我得到的数组 affectedRecords 只填充了 -2。所以如果 idList 包含 5 个元素:

实际输出:

Records affected: [-2, -2, -2, -2, -2]
5 Total updated

预期输出:

Records affected: [1, 1, 1, 1, 1]
5 Total updated

我在网上搜索了这个问题,发现了一些像这样的帖子: https://community.oracle.com/thread/3691652?start=0&tstart=0 https://community.oracle.com/thread/1046798?tstart=0

但是这些帖子中提供的解决方案也对我没有帮助,因为我已经在使用 ojdbc6.jar

那么这个问题有什么解决方案或替代方案吗?

作为 threads you link to describe,这不是 ojdbc6.jarojdbc5.jar 的问题,而是当前版本与旧版本的比较。

因此请确保您获得最新版本的驱动程序:

pick up ojdbc5.jar if you run the program with java 5

ojdbc6.jar if you run the program with java 6

then add/replace orai18n.jar

还要确保 java 选择正确的版本,可能是通过使用 java 的 -verbose 开关。

终于找到了。问题与 PreparedStatement.

有关

根据 Oracle here 的 Javadoc,我在使用 PreparedStatement 时无法获得每个查询影响的记录数。因此,当我将代码转换为 Statement 时,它运行良好。

参考注:

Update Counts in the Oracle Implementation of Standard Batching If a statement batch is processed successfully, then the integer array, or update counts array, returned by the statement executeBatch call will always have one element for each operation in the batch. In the Oracle implementation of standard update batching, the values of the array elements are as follows:

For a prepared statement batch, it is not possible to know the number of rows affected in the database by each individual statement in the batch. Therefore, all array elements have a value of -2. According to the JDBC 2.0 specification, a value of -2 indicates that the operation was successful but the number of rows affected is unknown.

For a generic statement batch, the array contains the actual update counts indicating the number of rows affected by each operation. The actual update counts can be provided only in the case of generic statements in the Oracle implementation of standard batching.

For a callable statement batch, the server always returns the value 1 as the update count, irrespective of the number rows affected by each operation.

-2SUCCESS_NO_INFO,因此它不会告诉您批处理中此元素更新了多少行。但是,从 11.2.0.3 开始,JDBC 瘦驱动程序会告诉您批处理中每个元素的更新行的确切数量。这是该版本的主要新功能之一。它适用于 PreparedStatement.