我在用jdbc开发web时,为什么报Operation not allowed after ResultSet closed错误。

xiechunmei13 2010-05-18 12:58:39
我有一个数据库工具类Mydb.java,它的代码如下:
public class Mydb {
private Connection conn = null;
private Statement stmt = null;
private ResultSet rs = null;
private PreparedStatement pstmt = null;
/**
* 这个方法不对外提供,除了这个类以外的都不需要调用
*/
private Connection getConn() {
try {

String driverClassName=Env.getInstance().getProperty("driver");
String url=Env.getInstance().getProperty("url");
String password=Env.getInstance().getProperty("password");
String user=Env.getInstance().getProperty("user");

ComboPooledDataSource cpds = new ComboPooledDataSource();
cpds.setDriverClass(driverClassName);
cpds.setJdbcUrl(url);
cpds.setUser(user);
cpds.setPassword(password);
cpds.setMaxStatements(180);
cpds.setMaxPoolSize(100);
conn=cpds.getConnection();

/*
Class.forName(driverClassName);
conn= DriverManager.getConnection(url,user,password);
*/
stmt = conn.createStatement();
} catch (Exception e) {
e.printStackTrace();
}
return conn;
}
public ResultSet getResultSet(String sql) {

try {
if(conn==null){
conn = getConn();
}
rs = stmt.executeQuery(sql);//第68行
} catch (SQLException e) {
e.printStackTrace();
}
return rs;
}

public int executeUpdate(String sql) {
int i=0;
try {
if(conn==null){
conn = getConn();
}
i=stmt.executeUpdate(sql);
} catch (SQLException e) {
e.printStackTrace();
}finally{
close();
}
return i;
}
public int execute(String sql) {
int i=0;
try {
if(conn==null){
conn = getConn();
}
i=stmt.executeUpdate(sql);
} catch (SQLException e) {
e.printStackTrace();
}
return i;
}
public void close() {
try {
if(rs != null) {
rs.close();
rs = null;
}
if(stmt != null) {
stmt.close();
stmt = null;
}
if(conn != null) {
conn.close();
conn = null;
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
但是我在另外一下类中写了一个方法,该方法中的代码如下:
public void run() {
System.out.println("系统自动检测是否存在应放入公海中的信息!");
int tel=0;//参数一
int sm1=0;//参数二
int sm2=0;//参数三
String rq1="";
String rq2="";
String rq3="";
String rq="";
int id=0;
String gh="";
String oldywy="";
String yywy="";
String sql="";
Mydb db=new Mydb();
ResultSet r=db.getResultSet("select tel,sm1,sm2 from t_cansubiao");
try {
if(r.next()){
tel=r.getInt("tel");
sm1=r.getInt("sm1");
sm2=r.getInt("sm2");
}
rq1=ShiJian.Jianhour(tel);
rq2=ShiJian.Jianday(sm1);
rq3=ShiJian.Jianday(sm2);
sql="select t_customer.id,t_customer.lxywy,t_user.username,t_customer.yywy from t_customer ,t_user where (t_customer.lxywy=t_user.gh) and ( t_customer.lx='客户' and t_customer.dhhfsj is null and t_customer.lrsj<'"+rq1+"') or ( t_customer.lx='客户' and t_customer.dhhfsj<>'' and t_customer.lrsj<'"+rq2+"') or ( t_customer.lx='客户' and t_customer.smhfsj<>'' and t_customer.smhfsj<'"+rq3+"')";
System.out.println("检测语句="+sql);
ResultSet rs=db.getResultSet(sql);
System.out.println("1============");
while(rs.next()){
id=rs.getInt("t_customer.id");//客户id号
gh=rs.getString("t_customer.lxywy");//联系业务员
yywy=rs.getString("t_customer.yywy")+"|"+rs.getString("t_user.username");
System.out.println("2============");
//存入联系过的表中
db.execute("insert t_lianxiguodekehu(khid,ywy) values('"+id+"','"+gh+"')");
//System.out.println("---------------------------");
//查到了,修改其类型,改为公海状态
System.out.println("3============");
db.execute("update t_customer set lx='公海' , lxywy='' , yywy='"+yywy+"' where id='"+id+"'");
System.out.println("4============");
}
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}finally{
db.close();
}
}
出现的错误,为什么只循环了一次,就报错误:java.sql.SQLException: Operation not allowed after ResultSet closed
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:910)
at com.mysql.jdbc.ResultSet.checkClosed(ResultSet.java:666)
at com.mysql.jdbc.ResultSet.next(ResultSet.java:7274)
at com.mchange.v2.c3p0.impl.NewProxyResultSet.next(NewProxyResultSet.java:3066)
at com.jykj.util.AdcTimerTask.run(AdcTimerTask.java:53)
请问应如何解决,给个详细的解决方案
...全文
903 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
xiechunmei13 2011-12-13
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 wodejiazaidongbeia 的回复:]
就像我这段代码:将红色那句注释起来,就执行正确,反之将报和你一样的错误!!
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbc:mysql:///schoolmanager","root","121");
Statement stm = conn.createS……
[/Quote]

很在理。
wodejiazaidongbeia 2010-07-15
  • 打赏
  • 举报
回复
就像我这段代码:将红色那句注释起来,就执行正确,反之将报和你一样的错误!!
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbc:mysql:///schoolmanager","root","121");
Statement stm = conn.createStatement();
String url ="insert into teacherinfo values (1349,'dd','33','m','fff')";
ResultSet rs = stm.executeQuery("select name from teacherinfo");
int t =9;
stm.executeUpdate(url);
System.out.println("fdsfdsafsaf");
while(rs.next())
{String name = new String(rs.getString("name").getBytes("ISO-8859-1"),"gb2312");
System.out.println(name);
System.out.println(t);
}
wodejiazaidongbeia 2010-07-15
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 liangchuanqi8624 的回复:]

一个statement不能同时打开2个resultset,在打开第2个之前请先关闭第一个。
[/Quote]


因为jdk文档说Statement执行时候默认会同一个时间之打开一个ResultSet,如果你同时打开两个,Statement所有的执行方法会默认隐性关闭当前的。所以你的这个语句:ResultSet rs=db.getResultSet(sql);,因为在getResultSet(sql)中已经返回一个了,你又创建了一个ResultSet rs ,所以Statement默认会将新创建的rs关闭。所以你得不到rs句柄!!可能是这个原因!!
yaowande123 2010-05-19
  • 打赏
  • 举报
回复
关注一下
xiechunmei13 2010-05-19
  • 打赏
  • 举报
回复
怎么没有回答呀
yaowande123 2010-05-19
  • 打赏
  • 举报
回复
这个贴子解决了,最终的解决方法是修改了Mydb.java类中的public int execute(String sql) {
int i=0;
try {
if(conn==null){
conn = getConn();
}
stmt = conn.createStatement(); //加上这句代码就不报错了
i=stmt.executeUpdate(sql);
} catch (SQLException e) {
e.printStackTrace();
}
return i;
}
传奇 2010-05-19
  • 打赏
  • 举报
回复
一个statement不能同时打开2个resultset,在打开第2个之前请先关闭第一个。
javafb 2010-05-19
  • 打赏
  • 举报
回复
你是db.close了,可是你是在finally里面关闭的,实际上你这个时候开启了2个resultset.

要么把你的逻辑分开,要么在开启第二个的时候先关闭第一个。

javafb 2010-05-19
  • 打赏
  • 举报
回复
楼主。。。。
你打开了2个resultset,
请在用第二个resultset的时候先关闭第一个resultset.
yaowande123 2010-05-19
  • 打赏
  • 举报
回复
学习了,帮顶一下
xiechunmei13 2010-05-18
  • 打赏
  • 举报
回复
楼上老兄,按你提供的方法,改了,还是报原来的错误,是不是在同一个方法中,不能同时出现二个ResultSet呀
,为什么我把下面的代码去掉就可以呀db.execute("insert t_lianxiguodekehu(khid,ywy) values('"+id+"','"+gh+"')");
//System.out.println("---------------------------");
//查到了,修改其类型,改为公海状态
System.out.println("3============");
db.execute("update t_customer set lx='公海' , lxywy='' , yywy='"+yywy+"' where id='"+id+"'");
wutian4567268 2010-05-18
  • 打赏
  • 举报
回复
抱歉,是我看错了

stmt = conn.createStatement();
改为
stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
试一下
xiechunmei13 2010-05-18
  • 打赏
  • 举报
回复
楼上老兄,方法execute中调用的executeUpdate,它是jdbc自身的方法,而不是Mydb.java中的executeUpdate方法呀
wutian4567268 2010-05-18
  • 打赏
  • 举报
回复
run方法循环调用了execute,而execute方法调用了executeUpdate,executeUpdate里面关闭了db
wutian4567268 2010-05-18
  • 打赏
  • 举报
回复
方法名错了是executeUpdate里面
finally{
close();
}
ChDw 2010-05-18
  • 打赏
  • 举报
回复
有些数据库是不允许在同一个Statement中打开两个ResultSet的,可能会自动关闭前一个ResultSet

你最好另外创建一个Statement来executeUpdate
xiechunmei13 2010-05-18
  • 打赏
  • 举报
回复
public int execute(String sql) {
int i=0;
try {
if(conn==null){
conn = getConn();
}
i=stmt.executeUpdate(sql);
} catch (SQLException e) {
e.printStackTrace();
}
return i;
}
楼上老兄,这是我Mydb中的execute方法,它没有调用关闭的方法呀
wutian4567268 2010-05-18
  • 打赏
  • 举报
回复
Mydb里的execute有调用close db的代码,但是没有open的,run里循环调用它,当第二次调用时就抱错,
建议把execute有调用close()方法的那句去掉

81,092

社区成员

发帖
与我相关
我的任务
社区描述
Java Web 开发
社区管理员
  • Web 开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧