日期:2014-05-17  浏览次数:20859 次

如何插入大量数据到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的方式。应该没问题,最好还是做手动提交,自动提交会有不可预知的事