如何避免 Java 中的 ResultSet is closed 异常?

新手上路,请多包涵

一旦我的代码到达我的 while(rs.next()) 循环,它就会产生 ResultSet is closed 异常。是什么导致了这个异常,我该如何纠正它?

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

原文由 Bobby 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.4k
2 个回答

听起来您在遍历第一条语句的结果集之前在同一连接中执行了另一条语句。如果您嵌套处理来自同一数据库的两个结果集,那么您就做错了。这些集合的组合应该在数据库端完成。

原文由 Apocalisp 发布,翻译遵循 CC BY-SA 2.5 许可协议

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

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 对象,一旦您对同一语句对象重新执行查询,所有与该语句关联的打开的结果集都会关闭。确保您没有关闭声明。

原文由 Sugar 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题