一个关于statement和resultset的不可解释的问题?在线等!

时间:2022-04-26 11:50:14
书里说:一个statement对应一个resultset
我的程序
<%!static Statement      stmt     = null;
static ResultSet      rset     = null;
public ResultSet executeQuery(String query) throws SQLException 
{
stmt = conn.createStatement();
rset = stmt.executeQuery(query);
return rset;
}%>(连库的函数可以先不考虑)
<%
ResultSet rest2=executeQuery("select * from ct_czlx");
executeQuery("select * from ct_yhjs");
while (rset.next()){out.println(rset.getString("MC"));}
while (rest2.next()){out.println(rest2.getString("MC"));}
%>
会报错:The cursor specified in a FETCH or CLOSE statement is not open
可是如过注释掉这句:while (rest2.next()){out.println(rest2.getString("MC"));}
加上这句out.println(rest2.getString("MC"));
可以打出数据,但是移动的话(next())就不行
最奇怪的是我原先的程序,和这段程序的结构差不多,连库的函数都一样,竟然不报错,实在不直到是为什么原因?

23 个解决方案

#1


有没有人知道阿,真的这么难?

#2


ResultSet rest2=executeQuery("select * from ct_czlx");
executeQuery("select * from ct_yhjs");
你这有错吧

#3


executeQuery是上面定义的函数,现在最可怕的是,执行这段程序后,应用服务器会自己重启服务,这到底是怎么回事啊

#4


创建两个Statment 
stm11,stmt2
Statement stmt1=conn.createStatement();   
ResultSet rs1 = stmt1.executeQuery(sql2);
Statement stmt2=conn.createStatement();   
ResultSet rs2 = stmt2.executeQuery(sql2);

#5


不会吧你用的什么服务器啊,BEAN能编译过吧

#6


你出的问题我也碰到过的,请看一下我的代码,原本我是用javabean连接数据库的,但是用javabean中封装的executeQuery函数来返回rs对象不能做下面的事情,会出错,没有办法,我只好直接连接数据库,创建多个Statement对象来完成下面的操作,测试通过了。我知道下面的做法很不好,我在测试使用连接数据库的javabean来返回Statement对象或Connection对象,但是没有成功,希望哪位能够提供一个更好的办法。
<%
Connection conn= DriverManager.getConnection(url,user,password);
Statement stmt=conn.createStatement();
    String sql1 = "select * from ProductType";
    ResultSet rs1 = stmt.executeQuery(sql1);


  int loop1 = 0;
    int loop2 = 0;
    int loop3 = 0;
    while(rs1.next()){
%>
       prodArr[<%=loop1%>] = new Object();
       prodArr[<%=loop1%>].Id = "<%=rs1.getString("ProductTypeID")%>";
       prodArr[<%=loop1%>].Name = "<%=rs1.getString("ProductTypeName")%>";
       
       prodArr[<%=loop1%>].seriesArr = new Array();
<%
      String sql2 = " select * from ProductSeries where ProductTypeID=" + rs1.getInt("ProductTypeID");
      Statement stmt2=conn.createStatement();   
      ResultSet rs2 = stmt2.executeQuery(sql2);
      loop2 = 0;
      while(rs2.next()){
%>
           prodArr[<%=loop1%>].seriesArr[<%=loop2%>] = new Object();
           prodArr[<%=loop1%>].seriesArr[<%=loop2%>].Id = "<%=rs2.getString("ProductSeriesID")%>";
           prodArr[<%=loop1%>].seriesArr[<%=loop2%>].Name = "<%=rs2.getString("ProductSeriesName")%>";
           
           prodArr[<%=loop1%>].seriesArr[<%=loop2%>].modelArr = new Array();
<%
        String sql3 = " select * from ProductModel where ProductSeriesID=" + rs2.getInt("ProductSeriesID");
        Statement stmt3=conn.createStatement();
        ResultSet rs3 = stmt3.executeQuery(sql3);
        loop3 = 0;
        while(rs3.next()){
%>
                   prodArr[<%=loop1%>].seriesArr[<%=loop2%>].modelArr[<%=loop3%>] = new Object();
                   prodArr[<%=loop1%>].seriesArr[<%=loop2%>].modelArr[<%=loop3%>].Id = "<%=rs3.getString("ProductModelID")%>";
                   prodArr[<%=loop1%>].seriesArr[<%=loop2%>].modelArr[<%=loop3%>].Name = "<%=rs3.getString("ProductModelName")%>";
<%
        loop3++;
        }
        rs3.close();
        stmt3.close();
      loop2++;
      }
      stmt2.close();
      rs2.close();
      loop1++;
    }
%>

#7


我是想知道用一个statement可否实现上面的程序,既然能够打印出数据rest2,而且其值不为空,那为什么不可以执行next()操作
至于重启,我想可能是服务器在执行这段程序的时候,发生了内部错误,至少服务器是这么说的,可能是由于游表,感觉也不至于重启阿

#8


我现在没有用javabean,我的executeQuery方法是封装在<%!...%>中的,完整的jsp程序(除了连接库的部分)都在上面。本来我是相信一个statement配一个resultset,但是原来的程序,基本格式就是这样,不报错,而我现在仿照写,就报错,所以觉得很奇怪,我就是想知道,用了静态的static来修饰statement,会不会又不一样的效果

#9


说说我的经验:要想用一个statement,前一个rs1执行完后不再用到此rs1结果集,这样再执行rs2就不会出错了

#10


static Statement stmt1=null;
   static ResultSet rest1=null;
   stmt1=conn1.createStatement();
   rest1=stmt1.executeQuery("select * from ct_czlx");
   ResultSet rest2=rest1;
   rest2.next();
   stmt1=conn1.createStatement();
   rest1=stmt1.executeQuery("select * from ct_yhjs");
   /*下面这句会导致错误:The cursor specified in a FETCH or CLOSE statement is not open.错误解释: The program attempted to either: (1) FETCH using a cursor, or (2) CLOSE a cursor at a time when the specified cursor was not open*/

   while (rest2.next()){out.println(rest2.getString("MC"));}
  /**
   *如果换上面这句为out.println(rset.getString("MC"));
   *可以输出正确结果,我想为什么能读出数据,不能下移cursor,
   */
   while (rest1.next()){}

#11


我发现是由于连接所造的,如果用自己写的数据库连接池程序,上面的程序就没有问题,但如果用应用服务器提供的数据源的这种数据库连接池的方法,就会有问题。前一种方法是jdbc1.0的规范,通过drivermanage来实现的,后一种方法是用数据源来实现的,但我想返回的连接对象应该是一样的,难道两种方法获得的连接还有什么不同呢?请高手指教!!

#12


现在已经很清楚了
用jdbc1.0的规范drivermanager来连库,,对于由两个statement(都是有一个连接对象产生)产生的两个resultset的访问不会有问题,但用jdbc2.0的数据源的数据库连接池的方法,就会报错,这是什么原因,我分析是不是数据库连接池的连接是已经创建好的,还是什么其他的原因,最后一次绝望up中!!

#13


本人也是菜鸟,但我想这里高手很少,至少看到这个帖子的人,都很难说出个所以然来,我提过一些问题也是如此,到后来没有办法给分,因为没有人能解决问题。建议你去一些国外的新闻组去问一下如:
comp.lang.java.beans
comp.lang.java.help
comp.lang.java.databases

#14


我知道怎么解决,可是这样子,我无法让封装在bean里的rset,和stmt关闭,我用一个方法,close,关闭stmt和rset,可是执行完后,竟然不关闭,不知道什么原因

#15


是这样的

一个connection可以产生多个statement,一个statement只能对应一个resultset
connnection关闭就关闭了所有它产生的stament,resultset,statement关闭就会关闭对应的resultset

至少jdbc2.0是这样的。1。0不记得了。

你上面虽然是创建的两个statement,但是赋给同一变量,当产生第二statement时,就覆盖了第一个statement.
导致出错。

你注释掉后的出错信息应该提供给大家。

#16


建议不要写这样的晦涩程序,
你如果要用一个connection产生多个statement,可以建立多个statement对象,
使用完毕每一对象进行显式地关闭

OK

#17


是这样的,我现在用数据库连接池做,我想就算conn.close()之后,也不是实际关闭conn,我现在是一个conn对应一个statement对应一个resultset,在结束后,分别关闭了rset,stat和conn。但是当执行第一遍的时候没事,当刷新一遍的时候报The cursor specified in an OPEN statement is already open的错误,且出错,不出错间续出现(就算关闭ie窗口,在打开,也是一样),请问这是什么原因

#18


目前的程序
 Connection conn1 = getConnection();
   Statement stmt1=conn1.createStatement();
   ResultSet rest1=stmt1.executeQuery("select * from ct_yhjs");
   Statement stmt2=conn1.createStatement();
   ResultSet rest2=stmt2.executeQuery("select * from ct_czlx fetch first 3 rows only");
   try{
   while (rest1.next()){out.println(rest1.getString("MC"));}
   //while (rest2.next()){out.println(rest2.getString("MC"));}
   }catch(Exception e){
out.println(e.toString());
   }
   rest1.close();
   rest2.close();
   stmt1.close();
   stmt2.close();
   conn1.close();
上面的getConnection是从连接池取到连接,上面的程序回报错,但是只要注释掉stmt2和rest2,就不会报错!请问何解?

#19


我想是因为你的连接池关闭的时机不对,或者说你的连接池设计不好

不知道你的连接池有没有重写executeQuery,有可能的一种情况是在执行第二次的时候
把第一次的结果集关闭了。所以我建议你跟踪一下这个执行过程,错误出现在那里.
问题肯定出现在不恰当的时候关闭了连接
这么看谁也看不出来。

#20


你用的什么数据库?版本?

这种问题我遇到过,是因为数据库厂商提供的驱动有问题

#21


我用的是db2v7.1,我现在发现好像和fetch语句也有一些关系,就是获取前几条纪录,不是这个错误:The cursor specified in a FETCH or CLOSE statement is not open
就是这个错误The cursor specified in an OPEN statement is already open,甚至有的时候会引起服务器的内部错误而重启服务,我想首先数据源是在服务器里配的,数据库连接池也是由数据源维护的,所以再不用数据库连接池的时候,一点错误都没有,在使用后,在多statement的情况下,尤其是还包含了fetch语句的情况下,就出现好多问题。我用的应用服务器是websphere3.5

#22


我最后想问一下,下面的错误的中文正确解释
The cursor specified in an OPEN statement is already open.  
Explanation: The program attempted to execute an OPEN statement for an open cursor. 
The statement cannot be processed. The cursor was unchanged. 
User Response: Correct the application program to ensure it does not attempt to execute an OPEN statement for a cursor already open. 

#23


搞定没?

建议按如下步骤进行测试:

1.单独测试select * from ct_czlx fetch first 3 rows only
2.测试select * from ct_yhjs和select * from ct_czlx 
3.再你原来的测试基础上,在select * from ct_czlx fetch first 3 rows only执行前/后关闭statement1.

#1


有没有人知道阿,真的这么难?

#2


ResultSet rest2=executeQuery("select * from ct_czlx");
executeQuery("select * from ct_yhjs");
你这有错吧

#3


executeQuery是上面定义的函数,现在最可怕的是,执行这段程序后,应用服务器会自己重启服务,这到底是怎么回事啊

#4


创建两个Statment 
stm11,stmt2
Statement stmt1=conn.createStatement();   
ResultSet rs1 = stmt1.executeQuery(sql2);
Statement stmt2=conn.createStatement();   
ResultSet rs2 = stmt2.executeQuery(sql2);

#5


不会吧你用的什么服务器啊,BEAN能编译过吧

#6


你出的问题我也碰到过的,请看一下我的代码,原本我是用javabean连接数据库的,但是用javabean中封装的executeQuery函数来返回rs对象不能做下面的事情,会出错,没有办法,我只好直接连接数据库,创建多个Statement对象来完成下面的操作,测试通过了。我知道下面的做法很不好,我在测试使用连接数据库的javabean来返回Statement对象或Connection对象,但是没有成功,希望哪位能够提供一个更好的办法。
<%
Connection conn= DriverManager.getConnection(url,user,password);
Statement stmt=conn.createStatement();
    String sql1 = "select * from ProductType";
    ResultSet rs1 = stmt.executeQuery(sql1);


  int loop1 = 0;
    int loop2 = 0;
    int loop3 = 0;
    while(rs1.next()){
%>
       prodArr[<%=loop1%>] = new Object();
       prodArr[<%=loop1%>].Id = "<%=rs1.getString("ProductTypeID")%>";
       prodArr[<%=loop1%>].Name = "<%=rs1.getString("ProductTypeName")%>";
       
       prodArr[<%=loop1%>].seriesArr = new Array();
<%
      String sql2 = " select * from ProductSeries where ProductTypeID=" + rs1.getInt("ProductTypeID");
      Statement stmt2=conn.createStatement();   
      ResultSet rs2 = stmt2.executeQuery(sql2);
      loop2 = 0;
      while(rs2.next()){
%>
           prodArr[<%=loop1%>].seriesArr[<%=loop2%>] = new Object();
           prodArr[<%=loop1%>].seriesArr[<%=loop2%>].Id = "<%=rs2.getString("ProductSeriesID")%>";
           prodArr[<%=loop1%>].seriesArr[<%=loop2%>].Name = "<%=rs2.getString("ProductSeriesName")%>";
           
           prodArr[<%=loop1%>].seriesArr[<%=loop2%>].modelArr = new Array();
<%
        String sql3 = " select * from ProductModel where ProductSeriesID=" + rs2.getInt("ProductSeriesID");
        Statement stmt3=conn.createStatement();
        ResultSet rs3 = stmt3.executeQuery(sql3);
        loop3 = 0;
        while(rs3.next()){
%>
                   prodArr[<%=loop1%>].seriesArr[<%=loop2%>].modelArr[<%=loop3%>] = new Object();
                   prodArr[<%=loop1%>].seriesArr[<%=loop2%>].modelArr[<%=loop3%>].Id = "<%=rs3.getString("ProductModelID")%>";
                   prodArr[<%=loop1%>].seriesArr[<%=loop2%>].modelArr[<%=loop3%>].Name = "<%=rs3.getString("ProductModelName")%>";
<%
        loop3++;
        }
        rs3.close();
        stmt3.close();
      loop2++;
      }
      stmt2.close();
      rs2.close();
      loop1++;
    }
%>

#7


我是想知道用一个statement可否实现上面的程序,既然能够打印出数据rest2,而且其值不为空,那为什么不可以执行next()操作
至于重启,我想可能是服务器在执行这段程序的时候,发生了内部错误,至少服务器是这么说的,可能是由于游表,感觉也不至于重启阿

#8


我现在没有用javabean,我的executeQuery方法是封装在<%!...%>中的,完整的jsp程序(除了连接库的部分)都在上面。本来我是相信一个statement配一个resultset,但是原来的程序,基本格式就是这样,不报错,而我现在仿照写,就报错,所以觉得很奇怪,我就是想知道,用了静态的static来修饰statement,会不会又不一样的效果

#9


说说我的经验:要想用一个statement,前一个rs1执行完后不再用到此rs1结果集,这样再执行rs2就不会出错了

#10


static Statement stmt1=null;
   static ResultSet rest1=null;
   stmt1=conn1.createStatement();
   rest1=stmt1.executeQuery("select * from ct_czlx");
   ResultSet rest2=rest1;
   rest2.next();
   stmt1=conn1.createStatement();
   rest1=stmt1.executeQuery("select * from ct_yhjs");
   /*下面这句会导致错误:The cursor specified in a FETCH or CLOSE statement is not open.错误解释: The program attempted to either: (1) FETCH using a cursor, or (2) CLOSE a cursor at a time when the specified cursor was not open*/

   while (rest2.next()){out.println(rest2.getString("MC"));}
  /**
   *如果换上面这句为out.println(rset.getString("MC"));
   *可以输出正确结果,我想为什么能读出数据,不能下移cursor,
   */
   while (rest1.next()){}

#11


我发现是由于连接所造的,如果用自己写的数据库连接池程序,上面的程序就没有问题,但如果用应用服务器提供的数据源的这种数据库连接池的方法,就会有问题。前一种方法是jdbc1.0的规范,通过drivermanage来实现的,后一种方法是用数据源来实现的,但我想返回的连接对象应该是一样的,难道两种方法获得的连接还有什么不同呢?请高手指教!!

#12


现在已经很清楚了
用jdbc1.0的规范drivermanager来连库,,对于由两个statement(都是有一个连接对象产生)产生的两个resultset的访问不会有问题,但用jdbc2.0的数据源的数据库连接池的方法,就会报错,这是什么原因,我分析是不是数据库连接池的连接是已经创建好的,还是什么其他的原因,最后一次绝望up中!!

#13


本人也是菜鸟,但我想这里高手很少,至少看到这个帖子的人,都很难说出个所以然来,我提过一些问题也是如此,到后来没有办法给分,因为没有人能解决问题。建议你去一些国外的新闻组去问一下如:
comp.lang.java.beans
comp.lang.java.help
comp.lang.java.databases

#14


我知道怎么解决,可是这样子,我无法让封装在bean里的rset,和stmt关闭,我用一个方法,close,关闭stmt和rset,可是执行完后,竟然不关闭,不知道什么原因

#15


是这样的

一个connection可以产生多个statement,一个statement只能对应一个resultset
connnection关闭就关闭了所有它产生的stament,resultset,statement关闭就会关闭对应的resultset

至少jdbc2.0是这样的。1。0不记得了。

你上面虽然是创建的两个statement,但是赋给同一变量,当产生第二statement时,就覆盖了第一个statement.
导致出错。

你注释掉后的出错信息应该提供给大家。

#16


建议不要写这样的晦涩程序,
你如果要用一个connection产生多个statement,可以建立多个statement对象,
使用完毕每一对象进行显式地关闭

OK

#17


是这样的,我现在用数据库连接池做,我想就算conn.close()之后,也不是实际关闭conn,我现在是一个conn对应一个statement对应一个resultset,在结束后,分别关闭了rset,stat和conn。但是当执行第一遍的时候没事,当刷新一遍的时候报The cursor specified in an OPEN statement is already open的错误,且出错,不出错间续出现(就算关闭ie窗口,在打开,也是一样),请问这是什么原因

#18


目前的程序
 Connection conn1 = getConnection();
   Statement stmt1=conn1.createStatement();
   ResultSet rest1=stmt1.executeQuery("select * from ct_yhjs");
   Statement stmt2=conn1.createStatement();
   ResultSet rest2=stmt2.executeQuery("select * from ct_czlx fetch first 3 rows only");
   try{
   while (rest1.next()){out.println(rest1.getString("MC"));}
   //while (rest2.next()){out.println(rest2.getString("MC"));}
   }catch(Exception e){
out.println(e.toString());
   }
   rest1.close();
   rest2.close();
   stmt1.close();
   stmt2.close();
   conn1.close();
上面的getConnection是从连接池取到连接,上面的程序回报错,但是只要注释掉stmt2和rest2,就不会报错!请问何解?

#19


我想是因为你的连接池关闭的时机不对,或者说你的连接池设计不好

不知道你的连接池有没有重写executeQuery,有可能的一种情况是在执行第二次的时候
把第一次的结果集关闭了。所以我建议你跟踪一下这个执行过程,错误出现在那里.
问题肯定出现在不恰当的时候关闭了连接
这么看谁也看不出来。

#20


你用的什么数据库?版本?

这种问题我遇到过,是因为数据库厂商提供的驱动有问题

#21


我用的是db2v7.1,我现在发现好像和fetch语句也有一些关系,就是获取前几条纪录,不是这个错误:The cursor specified in a FETCH or CLOSE statement is not open
就是这个错误The cursor specified in an OPEN statement is already open,甚至有的时候会引起服务器的内部错误而重启服务,我想首先数据源是在服务器里配的,数据库连接池也是由数据源维护的,所以再不用数据库连接池的时候,一点错误都没有,在使用后,在多statement的情况下,尤其是还包含了fetch语句的情况下,就出现好多问题。我用的应用服务器是websphere3.5

#22


我最后想问一下,下面的错误的中文正确解释
The cursor specified in an OPEN statement is already open.  
Explanation: The program attempted to execute an OPEN statement for an open cursor. 
The statement cannot be processed. The cursor was unchanged. 
User Response: Correct the application program to ensure it does not attempt to execute an OPEN statement for a cursor already open. 

#23


搞定没?

建议按如下步骤进行测试:

1.单独测试select * from ct_czlx fetch first 3 rows only
2.测试select * from ct_yhjs和select * from ct_czlx 
3.再你原来的测试基础上,在select * from ct_czlx fetch first 3 rows only执行前/后关闭statement1.