问题描述
在我的生命中,我无法看到它已经关闭"了
For the life of me I cannot see how it "is already closed"
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
public class RsetTest2 {
public static void main(String[] args) throws Exception {
String dbpath = "jdbc:h2:c:/mydb;IFEXISTS=TRUE;DB_CLOSE_ON_EXIT=FALSE;AUTO_SERVER=TRUE";
Connection conn = null;
System.setProperty("h2.bindAddress", "127.0.0.1");
Class.forName("org.h2.Driver");
conn = DriverManager.getConnection(dbpath, "sa", "sa");
conn.setAutoCommit(false);
System.out.println("success. querying database for latest values...");
Statement qry = conn.createStatement();
String sql = "select id from CONSTITUENTS where manager = 'abc' limit 1";
ResultSet rset = qry.executeQuery(sql);
while (rset.next()) {
int id = rset.getInt("id");
System.out.println(id);
qry.executeUpdate("insert into PAYREQUESTS (constituent, inblock) values (" + id + ", 238)");
}
rset.close();
qry.close();
}
}
这是输出:
success. querying database for latest values...
103
Exception in thread "main" org.h2.jdbc.JdbcSQLException: The object is already closed [90007-196]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:345)
at org.h2.message.DbException.get(DbException.java:179)
at org.h2.message.DbException.get(DbException.java:155)
at org.h2.message.DbException.get(DbException.java:144)
at org.h2.jdbc.JdbcResultSet.checkClosed(JdbcResultSet.java:3208)
at org.h2.jdbc.JdbcResultSet.next(JdbcResultSet.java:130)
at RsetTest2.main(RsetTest2.java:22)
其中22对应于"while(rset.next()){"行
where 22 corresponds to the "while (rset.next()) {" line
数据库正在返回值,请参阅使我们得到103的println语句.
the DB is returning values, see that println statement that gives us 103.
甚至更怪异的是,如果我//将executeUpdate行注释掉,那么一切都将正常完成
and even weirder, if I // comment out the executeUpdate line, it all completes normally
推荐答案
您的问题是您正在while
循环内重用SQL Statement
.一旦在循环中调用qry.executeUpdate(...)
方法,与前一条语句关联的ResultSet rset
就会关闭,因此会出现错误.是while(rset.next())
语句在循环失败的第一个executeUpdate(...)
之后被称为 .
Your problem is that you are reusing the SQL Statement
inside of your while
loop. As soon as you call the qry.executeUpdate(...)
method in the loop, the ResultSet rset
associated with the previous statement is closed, hence the error. It is the while(rset.next())
statement that is called after the first executeUpdate(...)
in the loop that fails.
如果您在循环中使用 new 语句,则该语句应该起作用.
If you use a new statement in the loop then it should work.
Statement qry = conn.createStatement();
String sql = "select id from CONSTITUENTS where manager = 'abc' limit 1";
ResultSet rset = qry.executeQuery(sql);
while (rset.next()) {
int id = rset.getInt("id");
System.out.println(id);
// we can't reuse the same Statement here so we need to create a new one
conn.createStatement().executeUpdate("insert into PAYREQUESTS ...");
}
您可以考虑保留一些必要的更新,然后在循环结束时发布更新.
You might consider keeping a collection of necessary updates and then issue the updates at the end of the loop.
是的,听起来不错.一点也不奇怪. :-)
Yep, that sounds right. Not weird at all. :-)
这篇关于org.h2.jdbc.JdbcSQLException:该对象已关闭的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!