如何避免 Java 中的结果集已关闭异常?

2022-09-01 12:21:17

一旦我的代码到达我的循环,它就会产生闭合异常。导致此异常的原因是什么,我该如何更正它?while(rs.next())ResultSet

编辑:我注意到在我的代码中,我正在与另一个,两个结果集来自同一个数据库嵌套循环,这是一个问题吗?while(rs.next())(rs2.next())


答案 1

听起来好像您在同一连接中执行了另一个语句,然后遍历第一个语句的结果集。如果要嵌套处理来自同一数据库的两个结果集,则操作出错。这些集合的组合应在数据库端完成。


答案 2

这可能是由多种原因引起的,包括您正在使用的驱动程序。

a) 某些驱动程序不允许嵌套语句。根据您的驱动程序是否支持 JDBC 3.0,您应该在创建 Statement 对象时检查第三个参数。例如,我在JayBird驱动程序到Firebird时遇到了同样的问题,但是代码在postgres驱动程序中工作正常。然后,我将第三个参数添加到 createStatement 方法调用中,并将其设置为 ResultSet.HOLD_CURSORS_OVER_COMMIT,并且 Firebird 的代码也开始正常工作。

static void testNestedRS() throws SQLException {

    Connection con =null;
    try {
        // GET A CONNECTION
        con = ConexionDesdeArchivo.obtenerConexion("examen-dest");
        String sql1 = "select * from reportes_clasificacion";

        Statement st1 = con.createStatement(
                ResultSet.TYPE_SCROLL_INSENSITIVE,
                ResultSet.CONCUR_READ_ONLY, 
                ResultSet.HOLD_CURSORS_OVER_COMMIT);
        ResultSet rs1 = null;

        try {
            // EXECUTE THE FIRST QRY
            rs1 = st1.executeQuery(sql1);

            while (rs1.next()) {
                // THIS LINE WILL BE PRINTED JUST ONCE ON
                                    // SOME DRIVERS UNLESS YOU CREATE THE STATEMENT 
                // WITH 3 PARAMETERS USING 
                                    // ResultSet.HOLD_CURSORS_OVER_COMMIT
                System.out.println("ST1 Row #: " + rs1.getRow());

                String sql2 = "select * from reportes";
                Statement st2 = con.createStatement(
                        ResultSet.TYPE_SCROLL_INSENSITIVE,
                        ResultSet.CONCUR_READ_ONLY);

                // EXECUTE THE SECOND QRY.  THIS CLOSES THE FIRST 
                // ResultSet ON SOME DRIVERS WITHOUT USING 
                                    // ResultSet.HOLD_CURSORS_OVER_COMMIT

                st2.executeQuery(sql2);

                st2.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            rs1.close();
            st1.close();
        }

    } catch (SQLException e) {

    } finally {
        con.close();

    }

}

b) 您的代码中可能存在错误。请记住,不能重用 Statement 对象,一旦对同一语句对象重新执行查询,与该语句关联的所有打开的结果集都将关闭。确保没有关闭语句。