ORACLE JDBC批处理执行不返回受影响行的实际计数

时间:2015-12-26 07:02:55

标签: java oracle jdbc batch-processing

我正在开发一个我正在使用 JDBC Oracle11 的应用程序。

我的表tbltest中有数十万条记录,我正在通过 JDBC 批量执行进行更新。因此,将其视为一个id =一个查询

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

以下是我的代码:

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成功更新。根据{{​​3}} Javadoc,在affectedRecords,我应该得到实际的不。由每个更新查询更新的记录,因为我没有得到任何异常。 相反,我只使用 -2 填充数组affectedRecords。因此,如果idList包含5个元素:

实际输出:

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

预期输出:

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

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

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

这个问题是否有解决方案或替代方案?

3 个答案:

答案 0 :(得分:5)

我终于找到了它。该问题与PreparedStatement

有关

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

参考注释:

  

在Oracle标准批处理实施中更新计数如果a   语句批处理成功处理,然后是整数数组,或   update count数组,由executeBatch调用语句返回   对于批处理中的每个操作,始终有一个元素。在Oracle中   执行标准更新批处理,数组的值   要素如下:

     

对于准备好的声明批处理,无法知道该数字   数据库中受每个单独语句影响的行数   批量。因此,所有数组元素的值都为-2。根据   在JDBC 2.0规范中,值为-2表示该操作   成功但受影响的行数未知。

     

对于通用语句批处理,该数组包含实际更新   计数表示每个操作影响的行数。该   实际更新计数只能在通用的情况下提供   Oracle实现标准批处理中的语句。

     

对于可调用语句批处理,服务器始终返回值1   作为更新计数,与每个受影响的行数无关   操作

答案 1 :(得分:1)

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

答案 2 :(得分:0)

作为threads you link to describe,它不是ojdbc6.jar vs ojdbc5.jar的问题,而是与那些版本的旧版本相比的当前版本。

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

  

如果使用java 5

运行程序,请选择ojdbc5.jar      

ojdbc6.jar如果你用java 6运行程序

     

然后添加/替换orai18n.jar

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