如何插入大量数据到Oracle数据库中
近日做一个短信平台的项目,需要将几十万的数据插入到Oracle数据库中,下面的代码在一百条数据下是正确执行的,但五百条的时候就报错。所报的错误为“
java.sql.SQLException:
ORA-00604: 递归 SQL 级别 1 出现错误
ORA-01000: 超出打开游标的最大数”,求大侠指教
Java code
try {
conn = getDba().getConnection();
conn.setAutoCommit(false);
for (TblMmsImpPhone importNum:numList) {
String sql = "insert into tbl_mms_importphone (id,phonenum,flag,temid) values(SEQ_TBL_IMPORTPHONE.nextval,'"+ importNum.getPhonenum()+ "',0,"+ importNum.getTemId() + ")";
ps = conn.prepareStatement(sql);
count += ps.executeUpdate();
if ((count % 100) == 0) {
conn.commit();
}
}
conn.commit();
conn.setAutoCommit(true);
} catch (Exception e) {
success = false;
try {
conn.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
e.printStackTrace();
} finally {
close(ps, conn);
}
------解决方案--------------------ORA-00604: 递归 SQL 级别 1 出现错误,ORA-01000: 超出打开游标的最大数
这两个错误一般出现在利用代码循环执行数据库命令(例如将数据导入到数据库)时,例如在C#中
1)建立一个OracleConnection
2)循环创建OracleCommand,并执行数据导入
3)关闭OracleConnection
当第二步的循环数比较小时,代码运行正常。当循环数超过一定值(例如300),代码就会出错。提示:
ORA-01000: 超出打开游标的最大数
这是因为Oracle数据库中打开的游标最大数为一定值,例如300,当代码中第二步时, 循环中一个Command占用了一个数据库游标,执行的循环超过这个数时就会产生游标数目溢出错误。
解决办法:
第二步循环中中每次执行完OracleCommand,都将command.dispose()下,释放掉这个资源就好了
此外,也可以修改数据库的最大游标数,不过这个方法治标不治本。
------解决方案--------------------
首先把insert语句改成insert into tbl_mms_importphone (id,phonenum,flag,temid) values(?,?,?,?)的形式,这样可以减少sql编译的时间。
其次改成batch update的方式
ps = conn.prepareStatement(sql);
ps.addBatch();
判断batch数目然后ps.executeBatch();
------解决方案--------------------这个我好像遇到过一次,和ORACLE的配置有关系,因为你用的是一个连接提交大量数据在oracle中要重新配置,修改oracle中的配置。
prepareStatement没必要吧,这个是处理带占位符的,你也没用啊?
还有你用的是连接池吧?
你采用3楼的方式:改成batch update的方式。应该没问题,最好还是做手动提交,自动提交会有不可预知的事