我有一个应用程序,它处理一个非常大的文件并将数据发送到oracle数据库(使用Java 6,oracle 9)。
在循环中,我使用PreparedStatement ps
并创建使用ps.addBatch()
生成的所有SQL语句。
我遇到BatchUpdateException bue
期间某处ps.executeBatch()
被抛出的情况。此时,批处理停止执行。
我希望批量执行继续,以便我可以检查方法processUpdateCounts(bue.getUpdateCounts())
中的失败更新。
关于类BatchUpdateException的javadoc说:
批量更新中的命令后 无法正确执行和a 抛出BatchUpdateException, 司机可能会或可能不会继续 处理中的其余命令 批次。
有没有办法强制继续,还是我需要改变我的程序才能单独执行语句?
答案 0 :(得分:5)
刚刚找到此链接: JDBC Batch Update Problem
显然,它说有
因此,我正在逐个发送插入物。 谢谢没有办法使用ORACLE BATCH JDBC 在第一次失败后继续,
(抱歉没有好好找到上面的链接)。
答案 1 :(得分:3)
有一种解决方法可以让您使用批处理功能。您可以执行适当处理错误的PL / SQL块,而不是执行简单的INSERT语句:
BEGIN
INSERT INTO your_table VALUES (?,?,...?);
EXCEPTION
WHEN OTHERS THEN
/* deal with the error. For example, log the error id and error msg
so that you can list them after the batch */
INSERT INTO error_table VALUES (?, sqlerrm);
END
性能应该与批量插入相同(应该比单独执行语句更快)。您也可以调用存储过程而不是PL / SQL块。
答案 2 :(得分:1)
Oracle本身可以看到:http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14250/oci04sql.htm#sthref616
但是,似乎这个功能似乎没有暴露给JDBC,即使在特定于oracle的类中也没有。
由于相当无用的JDBC错误处理(“驱动程序可能会或可能不会继续”),我总是在批处理之前设置一个保存点,并在出错时执行回滚。这是在Oracle Batch Error之后建立已知状态的唯一符合JDBC的方法 - 据我所知。
答案 3 :(得分:0)
由于规范似乎没有强制要求(如Javadoc所示),任何“强制”继续都必须在每个驱动程序的基础上完成。一个简单的符合标准的解决方法是检查getUpdateCounts()
返回的数组,并为那些失败的语句“重新运行”批处理。您可以通过为重试次数设置逻辑来使这种方法更复杂。
当然,这看起来有点混乱(跟踪添加的“批处理”然后检查输出)但是可以在所有数据库和驱动程序实现中工作。只是一个想法...