同一方法执行executeQuery与executeUpdate报错:PSQLException: This ResultSet is closed
解决PSQLException: This ResultSet is closed的问题
嗨,这个问题我太熟了!根源其实是JDBC的基础规范:同一个Statement对象在执行新的SQL操作时,会自动关闭之前通过它生成的ResultSet。你在遍历rs的过程中调用stmt.executeUpdate,相当于用同一个Statement开了新的操作,直接把还在使用的ResultSet给关了,后面再调用rs.next()肯定就报错啦。
下面给你两个靠谱的解决方案,都是经过实践验证的:
方案一:用两个独立的Statement对象
给查询和更新操作分别创建专属的Statement,让它们的操作互不干扰。修改你的代码如下:
Statement queryStmt = pc.getStatement(); Statement updateStmt = pc.getStatement(); try { ResultSet rs = queryStmt.executeQuery("select * from artigos where artigoc=" + s); while (rs.next()) { int stock = rs.getInt("stock"); // 用updateStmt执行更新,不会影响queryStmt对应的ResultSet updateStmt.executeUpdate("update artigos set stock = ... where artigoc=" + s); } // 手动关闭资源(如果不用try-with-resources的话) rs.close(); queryStmt.close(); updateStmt.close(); } catch (SQLException e) { e.printStackTrace(); }
方案二:优先使用PreparedStatement(更推荐)
这个方案不仅能解决你的ResultSet关闭问题,还能避免SQL注入风险,代码也更健壮。同样用两个独立的PreparedStatement来处理查询和更新:
// 预定义SQL模板,用?作为参数占位符 String querySql = "select * from artigos where artigoc = ?"; String updateSql = "update artigos set stock = ? where artigoc = ?"; // 用try-with-resources语法,自动关闭资源,不用手动写close try (PreparedStatement queryPstmt = pc.prepareStatement(querySql); PreparedStatement updatePstmt = pc.prepareStatement(updateSql)) { // 设置查询的参数 queryPstmt.setString(1, s); ResultSet rs = queryPstmt.executeQuery(); while (rs.next()) { int stock = rs.getInt("stock"); // 这里可以根据业务逻辑修改stock值,比如stock减1 int updatedStock = stock - 1; // 设置更新操作的参数 updatePstmt.setInt(1, updatedStock); updatePstmt.setString(2, s); updatePstmt.executeUpdate(); } rs.close(); } catch (SQLException e) { e.printStackTrace(); }
另外,你之前尝试创建新Statement但没解决,大概率是因为你在循环内部创建Statement,或者没有确保查询和更新用的是完全独立的对象。按照上面的方式分开创建两个独立的Statement/PreparedStatement,问题肯定能解决。
内容的提问来源于stack exchange,提问作者Filipe Carvalho
相关产品推荐
相关产品推荐

