获取 java.sql.SQLException:结果集关闭后不允许操作
当我执行以下代码时,出现异常。我认为这是因为我正在使用相同的连接对象准备新的语句。我应该如何重写它,以便我可以创建准备好的语句并开始使用 rs2?即使连接是到同一个数据库,我是否也必须创建一个新的连接对象?
try
{
//Get some stuff
String name = "";
String sql = "SELECT `name` FROM `user` WHERE `id` = " + userId + " LIMIT 1;";
ResultSet rs = statement.executeQuery(sql);
if(rs.next())
{
name = rs.getString("name");
}
String sql2 = "SELECT `id` FROM `profiles` WHERE `id` =" + profId + ";";
ResultSet rs2 = statement.executeQuery(sql2);
String updateSql = "INSERT INTO `blah`............";
PreparedStatement pst = (PreparedStatement)connection.prepareStatement(updateSql);
while(rs2.next())
{
int id = rs2.getInt("id");
int stuff = getStuff(id);
pst.setInt(1, stuff);
pst.addBatch();
}
pst.executeBatch();
}
catch (Exception e)
{
e.printStackTrace();
}
private int getStuff(int id)
{
try
{
String sql = "SELECT ......;";
ResultSet rs = statement.executeQuery(sql);
if(rs.next())
{
return rs.getInt("something");
}
return -1;
}//code continues
When I execute the following code, I get an exception. I think it is because I'm preparing in new statement with he same connection object. How should I rewrite this so that I can create a prepared statement AND get to use rs2? Do I have to create a new connection object even if the connection is to the same DB?
try
{
//Get some stuff
String name = "";
String sql = "SELECT `name` FROM `user` WHERE `id` = " + userId + " LIMIT 1;";
ResultSet rs = statement.executeQuery(sql);
if(rs.next())
{
name = rs.getString("name");
}
String sql2 = "SELECT `id` FROM `profiles` WHERE `id` =" + profId + ";";
ResultSet rs2 = statement.executeQuery(sql2);
String updateSql = "INSERT INTO `blah`............";
PreparedStatement pst = (PreparedStatement)connection.prepareStatement(updateSql);
while(rs2.next())
{
int id = rs2.getInt("id");
int stuff = getStuff(id);
pst.setInt(1, stuff);
pst.addBatch();
}
pst.executeBatch();
}
catch (Exception e)
{
e.printStackTrace();
}
private int getStuff(int id)
{
try
{
String sql = "SELECT ......;";
ResultSet rs = statement.executeQuery(sql);
if(rs.next())
{
return rs.getInt("something");
}
return -1;
}//code continues
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
问题在于您在
getStuff()
中获取数据的方式。每次访问getStuff()
时,您都会获得一个新的ResultSet
,但不会关闭它。这违反了
Statement
类的期望(请参见此处 - http://docs.oracle.com/javase/7/docs/api/java/sql/Statement.html):让事情变得更糟的是调用代码中的 rs 。它也是从
statement
字段派生出来的,但它不是封闭的。底线:您同时打开了与同一个
Statement
对象相关的多个ResultSet
。The problem is with the way you fetch data in
getStuff()
. Each time you visitgetStuff()
you obtain a freshResultSet
but you don't close it.This violates the expectation of the
Statement
class (see here - http://docs.oracle.com/javase/7/docs/api/java/sql/Statement.html):What makes things even worse is the
rs
from the calling code. It is also derived off-of thestatement
field but it is not closed.Bottom line: you have several
ResultSet
pertaining to the sameStatement
object concurrently opened.我猜想在
while(rs2.next())
之后您正在尝试从 rs1 访问某些内容。但自从您重新执行语句以从中获取 rs2 以来,它已经关闭了。由于您没有关闭它,我相信它在下面再次被使用。I guess after
while(rs2.next())
you are trying to access something from rs1. But it's already closed since you reexecuted statement to get rs2 from it. Since you didn't close it, I beleive it's used again below.