ExecuteBatch方法在java中返回值为-2的数组

当我在java中执行executeBatch方法时,它返回一个很好的int数组,但是所有数组元素的值都是-2,

它应该是0或+ ve数字,显示受影响的行数,但它返回-2,

当我在数据库中检查它时,所有更新都成功完成。 请解释这-2的含义是什么,以及我如何找到受影响的行数。

谢谢,Deepesh Uniyal

关于批量更新的返回代码,jdbc-spec有如下说明:

■0或更高 – 命令已成功处理,值为更新计数,指示数据库中受命令执行影响的行数第14章批处理更新121

■Statement.SUCCESS_NO_INFO – 命令已成功处理,但受影响的行数未知

Statement.SUCCESS_NO_INFO定义为-2,因此您的结果表明一切正常,但您不会获得有关更新列数的信息。

oracle文档说明:

•对于预准备语句批处理,无法通过批处理中的每个单独语句了解数据库中受影响的行数。 因此,所有数组元素的值都为-2。 根据JDBC 2.0规范,值-2表示操作成功但受影响的行数未知。

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

•对于可调用语句批处理,服务器始终返回值1作为更新计数,而不考虑每个操作影响的行数。

因此,如果您需要更新计数,您似乎无法使用PreparedStatement但必须回退到简单的Statement

值-2表示元素已成功处理,但受影响的行数未知。

眼镜

请注意,由于Oracle 12c不再是这种情况:

对于预准备语句批处理,该数组包含实际更新计数,指示每个操作影响的行数。

请参阅https://docs.oracle.com/database/121/JJDBC/oraperf.htm#JJDBC28773

标准更新批处理…

 conn.setAutoCommit(false); PreparedStatement pstmt = conn.prepareStatement("INSERT INTO employees VALUES(?, ?)"); pstmt.setInt(1, 2000); pstmt.setString(2, "Milo Mumford"); pstmt.addBatch(); pstmt.setInt(1, 3000); pstmt.setString(2, "Sulu Simpson"); pstmt.addBatch(); int[] updateCounts = pstmt.executeBatch(); conn.commit(); pstmt.close(); ... 

您可以处理更新计数数组以确定批处理是否成功处理。

标准批处理的Oracle实现中的error handling
如果任何一个批处理操作未能成功完成或尝试在executeBatch调用期间返回结果集,则处理将停止并生成java.sql.BatchUpdateException。

在批处理exception之后,可以使用BatchUpdateException对象的getUpdateCounts方法检索更新计数数组。 这将返回一个更新计数的int数组,就像executeBatch方法一样。 在标准更新批处理的Oracle实现中,处理批处理后,更新计数数组的内容如下:

  • 对于准备好的语句批处理,如果批处理执行之间出错,则executeBatch方法不能返回值,而是抛出BatchUpdateException。 在这种情况下,exception本身携带一个大小为n的int数组作为其数据,其中n是成功记录执行的次数。 例如,如果批处理的大小为5且错误发生在第4条记录中,则BatchUpdateException具有大小为3的数组(成功执行3条记录),并且数组中的每个项目表示每个项目受影响的行数。 。

  • 对于通用语句批处理或可调用语句批处理,update counts数组只是包含实际更新的部分数组
    计算到错误点。 可以提供实际的更新计数,因为Oracle JDBC无法在标准更新的Oracle实现中对通用和可调用语句使用真正的批处理
    配料。

例如,如果批处理中有20个操作,前13个成功,第14个生成exception,则更新计数数组将包含13个元素,包含成功操作的实际更新计数。

您可以根据需要在这种情况下提交或回滚成功的操作。

在您的代码中,在处理批处理失败时,您应该准备好在发生exception时处理数组元素中的-3或真实更新计数。 对于失败的批处理,您将具有-3的完整数组或正整数的部分数组。