Oracle数据库,在循环中操作大量SQL语句时,如果发生了异常,会导致直到连接关闭时,才能释放游标。这样如果循环次数较多时,就会出现以下错误,导致执行失败:
java.sql.SQLException: ORA-00604: 递归 SQL 级别 1 出现错误
ORA-01000: 超出打开游标的最大数
ORA-00604: 递归 SQL 级别 1 出现错误
ORA-01000: 超出打开游标的最大数
ORA-01000: 超出打开游标的最大数
DbPro.java中,比如query方法,pst创建执行后,无异常可以正确关闭,但如果DbKit.close(rs,pst)之前出现了异常,则无法立即关闭,需等到conn关闭后才能关闭。
<T> List<T> query(Config config, Connection conn, String sql, Object... paras) throws SQLException { List result = new ArrayList(); PreparedStatement pst = conn.prepareStatement(sql); config.dialect.fillStatement(pst, paras); ResultSet rs = pst.executeQuery(); int colAmount = rs.getMetaData().getColumnCount(); if (colAmount > 1) { while (rs.next()) { Object[] temp = new Object[colAmount]; for (int i = 0; i < colAmount; i++) { temp[i] = rs.getObject(i + 1); } result.add(temp); } } else if (colAmount == 1) { while (rs.next()) { result.add(rs.getObject(1)); } } DbKit.close(rs, pst); return result; }
如下修改后,解决此异常:
<T> List<T> query(Config config, Connection conn, String sql, Object... paras) throws SQLException { List result = new ArrayList(); PreparedStatement pst = null; ResultSet rs = null; try { pst = conn.prepareStatement(sql); config.dialect.fillStatement(pst, paras); rs = pst.executeQuery(); int colAmount = rs.getMetaData().getColumnCount(); if (colAmount > 1) { while (rs.next()) { Object[] temp = new Object[colAmount]; for (int i = 0; i < colAmount; i++) { temp[i] = rs.getObject(i + 1); } result.add(temp); } } else if (colAmount == 1) { while (rs.next()) { result.add(rs.getObject(1)); } } } finally { DbKit.close(rs, pst); } return result; }
这个类中,有多个方法存在此问题。