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();
}
}
感謝您的任何建議
之後調用
PreparedStatement.clearParameters()
你可以調整'OPEN_CURSORS' ...但是無論如何,確保你清理了你的ResultSet's。 – oldrinb爲什麼你要關閉你的'stmt'對象並且'create'又是一樣的?爲什麼不重新使用相同的'stmt'而不關閉? – Sujay
@Sujay是正確的;嘗試'PreparedStatement.clearParameters' – oldrinb