ORA-01000: 超出打開遊標的最大數 問題的分析和解決

 
最近項目中報錯:
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112)

代碼:
for (MzLoadAcctCodeInfoDto dto : list) {
logger.info(qrySqlSb.toString());
ps = conn.prepareStatement(qrySqlSb.toString());
PreparedStatementHelper.setParam(1, dto.getAcctId(), ps);
rs = ps.executeQuery();
while(rs.next()) {
dbloopOne = 1;
ps = conn.prepareStatement(insertSqlSb.toString());
PreparedStatementHelper.setParam(dbloopOne++, dto.getAgreementCode(), ps);
PreparedStatementHelper.setParam(dbloopOne++, dto.getPartnerCode(), ps);
PreparedStatementHelper.setParam(dbloopOne++, rs.getString(1), ps);
PreparedStatementHelper.setParam(dbloopOne++, rs.getString(2), ps);
ps.executeUpdate();

dbloopOne = 1;
ps = conn.prepareStatement(deleteSqlSb.toString());
PreparedStatementHelper.setParam(dbloopOne++, dto.getAgreementCode(), ps);
PreparedStatementHelper.setParam(dbloopOne++, dto.getPartnerCode(), ps);
PreparedStatementHelper.setParam(dbloopOne++, dto.getAccNbr(), ps);
ps.executeUpdate();

num++;
}
}
在java代碼中,執行conn.createStatement()和conn.prepareStatement()的時候,實際上都是相當與在數據庫中打開了一個cursor。尤其是,如果你的createStatement和prepareStatement是在一個循環裏面的話,就會非常容易出現這個問題。因爲遊標一直在不停的打開,而且沒有關閉。
     一般來說,我們在寫Java代碼的時候,createStatement和prepareStatement都應該要放在循環外面,而且使用了這些Statment後,及時關閉。最好是在執行了一次executeQuery、executeUpdate等之後,如果不需要使用結果集(ResultSet)的數據,就馬上將Statment關閉,調用close()方法。
解決方法:
1、增大遊標的數量(不可取)
分析:
1.1、顯然這種方法治標不治本,遊標的數量往往設置一個 較小值即可,除非特殊情況;
1.2、應用程序不同,該值也不同
1.3、並麼有根除代碼上的缺陷
2、修改代碼:
Java代碼在執行conn.createStatement()和 conn.prepareStatement()的時候,實際上都是相當與在數據庫中打開了一個cursor,
當PreparedStatement或statement執行操作之後,如果不需要使用結果集(ResultSet)的數據,就馬上將Statement或PreparedStatement關閉。
尤其是在循環中,因爲遊標一直在不停的打開,而且沒有關閉;
綜上所述:上面的代碼在pstmt.execute();之後執行pstmt.close();方法即可
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章