2012-08-27 88 views
2

我使用批量更新准备了数以百万计的记录语句,但最终还是遇到了以下错误在运行时> 400K的记录执行后。ORA-01000:最大打开的游标超出批量更新的PreparedStatement

值java.sql.SQLException:ORA-01000:最大打开的游标超出

我不知道这是由下面的代码

try{  
conn = ConnectionManager.getConnection(); 
// turn off autocommit 
conn.setAutoCommit(false); 

PreparedStatement stmt = conn.prepareStatement(query); 

//for each of the records to be updated 
for(int k=0;k<objects.length;k++) { 

    stmt.setString(1, objects[k].getValueA()); 
    stmt.setString(2, objects[k].getValueB()); 

    stmt.addBatch(); 

    //running batch execute on every 10000 records 
    if(k%10000 == 0 || k == objects.length-1) { 
     // submit the batch for execution 
     int[] updateCounts = stmt.executeBatch(); 

     conn.commit(); 

     if(k < objects.length-1) 
     { 
      stmt.close(); 
      stmt = conn.prepareStatement(query); 
     } 
    } 
} 
}catch(Exception e) { 
    e.printStackTrace(); 
}finally { 
    if(conn!=null){ 
     conn.close(); 
    } 
} 

,从而引起PreparedStatement的是在提交连接后关闭并用新的PreparedStatement替换。我不确定是否重复提交相同的连接可能会导致此问题。

任何人都可以提出问题的解决方案或建议更好的体系结构来处理预准备语句的批处理更新。

P/S:错误行实际上指向删除语句执行,但我不认为这是根本原因,如前面前批量更新准备的语句代码添加这个问题不存在。

try { 
    if (hasData) { 
     conn = ConnectionManager.getConnection(); 
     CommonStore.deleteRecords(conn, queryStr); //the error point to this line 
     hasData = false; 
    } 
}catch(Exception e) { 
    e.printStackTrace(); 
}finally { 
    if(conn!=null){ 
     conn.close(); 
    } 
} 

感谢您的任何建议

+0

之后调用PreparedStatement.clearParameters()你可以调整'OPEN_CURSORS' ...但是无论如何,确保你清理了你的ResultSet's。 – oldrinb

+0

为什么你要关闭你的'stmt'对象并且'create'又是一样的?为什么不重新使用相同的'stmt'而不关闭? – Sujay

+0

@Sujay是正确的;尝试'PreparedStatement.clearParameters' – oldrinb

回答

0

一两件事,我观察到的是这样的:

if(k < objects.length-1) 
{ 
    stmt.close(); 
    stmt = conn.prepareStatement(query); 
} 

而不是closingstmt对象,我会建议重新使用。这只是一个可以避免的开销。

我不认为它会起任何作用,关闭并重新打开同一PreparedStatement。另外,你可以考虑在addBatch()

相关问题