Java代码工具箱之超出游标最大数

1. Java大量写入oracle时容易出现此错。经过此错,也触动自己要深刻理解 java 的 prepareStatement 等对象,及数据库的连接与释放。

2. 原因:经常会出现在 for 循环中进行数据库写入操作。

3. 案例:我在将Excel导入到Oracle数据库中时,在遍历Excel的每一行数据时,都执行了语句

 conn.prepareStatement(sql); 

结果每次执行到2000行时出现游标错误。更正后,一次顺利导入5000条数据。

class myCode{

Connection con = null;
PreparedStatement pre = null;
ResultSet result = null;

void readExcel(){
for(...)
     for(...)
           update();
}


void update(){
    String sql = "update myTabe set A=? where id=?";
    pre = conn.prepareStatement(sql);
    pre.setString(1,A);
    pre.setLong(2, 123);
    
    pre.executeUpdate();

    //报错
}


static void main(String[] args){
      connDB()
      initDbObj()
      readExcel()
   close(DbOjb)()//close ps,rs
    closeDB()//close conn
} }

正确的 update()函数应该如下:(2017年5月26日 更新,下方法也不是很好的实践代码,最好的做法将conn.prepareStatement提出到for循环外)

//正确代码
void update(){
    String sql = "update myTabe set A=? where id=?";
    pre = conn.prepareStatement(sql);
    pre.setString(1,A);
    pre.setLong(2, 123);
    
    pre.executeUpdate();

    //重点
    if(  pre != null ){
        pre.close();
    }
}


//pre对象用完必须立马关闭,不要放到最后和 conn一起关闭。
//否则,每次pre被设置一次,就会申请一个游标,一般游标才300个
//很快就会报错。

 

——————————————————————

2017年5月26日 更新:上面代码有问题。

    String sql = "update myTabe set A=? where id=?";
    pre = conn.prepareStatement(sql);

根本不应该放在 for 循环内部。应提出到 for 循环之外的上面。

更合适的代码应该为:

class myCode{

Connection con = null;
PreparedStatement pre = null;
ResultSet result = null;

String sql = "update myTabe set A=? where id=?";
pre = conn.prepareStatement(sql);

void readExcel(){
for(...)
     for(...)
           update();
}


void update(){

    pre.setString(1,A);
    pre.setLong(2, 123);
    
    pre.executeUpdate();

}


static void main(String[] args){
      connDB()
      initDbObj()
      readExcel()

  close(DbOjb)()//close ps,rs
    closeDB()//close conn
} }

或者使用较复杂的 “PreparedStatement的批量提交功能” 。

 

posted @ 2017-05-21 12:26  HolyGrail  阅读(616)  评论(0编辑  收藏  举报
设计良好的程序将用户的注意力视为有限的宝贵资源,只有在必要时才要求使用。 ——《Unix编程艺术》