2011-06-16 52 views
10

我有非常简单的代码:ResultSet:异常:集合类型是TYPE_FORWARD_ONLY - 为什么?

pstat=con.prepareStatement("select typeid from users where username=? and password=?");    
pstat.setString(1, username); 
pstat.setString(2, password); 
rs=pstat.executeQuery(); 
int rowCount=0; 
while(rs.next()) 
{  
    rowCount++;   
} 
rs.beforeFirst(); 
if(rowCount>=1) 
{ 
while(rs.next()) 
{ 
    typeID=rs.getInt(1); 
} 

但是,当执行此代码我得到...

java.sql.SQLException: Result set type is TYPE_FORWARD_ONLY 
at sun.jdbc.odbc.JdbcOdbcResultSet.beforeFirst(Unknown Source) 
at server.ClientImpl.login(ClientImpl.java:57) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) 
at java.lang.reflect.Method.invoke(Unknown Source) 
at sun.rmi.server.UnicastServerRef.dispatch(Unknown Source) 
at sun.rmi.transport.Transport$1.run(Unknown Source) 
at java.security.AccessController.doPrivileged(Native Method) 
at sun.rmi.transport.Transport.serviceCall(Unknown Source) 
at sun.rmi.transport.tcp.TCPTransport.handleMessages(Unknown Source) 
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(Unknown Source) 
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown Source) 
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) 
at java.lang.Thread.run(Unknown Source) 

是什么原因造成这一点,我怎么能解决这个问题?

回答

13

类型TYPE_FORWARD_ONLY意味着你只能向前的结果集,而不是落后,所以当您尝试与beforeFirst()回去得到一个异常。相反,你可以使用以下prepareStatement(),接收ResultSet类型作为参数,或做:

 pstat=con.prepareStatement("select typeid from users where username=? and password=?");    
     pstat.setString(1, username); 
     pstat.setString(2, password); 
     rs=pstat.executeQuery(); 
     int rowCount=0; 

     while(rs.next()) 
     { 
      rowCount++; 
      typeID=rs.getInt(1); 
     } 
+0

我正打算输入那个。干得好,@MByD – jpm 2011-06-16 06:11:52

+0

@jpm - 非常感谢! :) – MByD 2011-06-16 06:18:30

3

像异常说:你不能滚动你的结果比前锋任何其它方向设置。所以,当你遍历结果集,以获得行数(我甚至不明白你为什么这样做),那么该行会抛出该异常:

rs.beforeFirst(); 

,因为这会向后滚动。

要么创建您的语句,以便您可以滚动它(例如谷歌)或删除行计数。我建议后者,因为计数似乎没有必要。

16

更改您的第一条语句这个

pstat=con.prepareStatement("select typeid from users where username=? and password=?", 
          ResultSet.TYPE_SCROLL_SENSITIVE, 
         ResultSet.CONCUR_UPDATABLE); 

这样你就可以前进,后退,东西,所以少操心

6

你只能用一个结果是类型TYPE_SCROLL_SENSITIVE的做到这一点,其定义为“该常数指示可滚动的ResultSet对象的类型,并且通常对其他人所做的更改敏感。”

你需要做类似下面的...

Statement statement = 
connection.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, 
    ResultSet.CONCUR_READ_ONLY); 
0

根据rowCount变量是没有必要的。你正在rs上执行两个循环。仅第二环路是必要的以获得其通过的这部分代码进行行数:

while (rs.next()){ 
typeID=rs.getInt(1); //typeID is the number of rows in the ResultSet 
} 
2

java.sql.SQLException中:结果集类型是TYPE_FORWARD_ONLY

用JDBC 2.0 API,用户可以灵活地向前或向后移动光标。

你的错误可以通过创建statemnt被删除如下

Statement st = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY); 

此外,一个更好的方法来计算行数将

rs=pstat.executeQuery();    //execute the query 
rs.last();        //move the cursor to the last row 
int numberOfRows = rs.getRow();   //get the number of rows 
rs.beforeFirst();      //back to initial state 
2

这个问题是很老。我相信这个解决方案已经找到了。不过,我想在这里建议一些与Aditya不同的东西。

pstat=con.prepareStatement("select typeid from users where username=? and password=?", 
           ResultSet.TYPE_SCROLL_INSENSITIVE, 
          ResultSet.CONCUR_UPDATABLE); 

相反ResultSet.TYPE_SCROLL_SENSITIVE的,我会用不敏感

Check this link for refernce

4

尽管这个问题的时候,答案没有老化,今天遇到了类似的问题,这是我走近它,如here 这是由Java JDBC驱动程序和PostgreSQL数据库提供的功能。 这种情况下使用默认参数创建Statement对象时,系统生成的数据集只能是一个方向前进的指针,而不是双向移动数据记录指针,前者

声明语句= dbConn.createStatement();
结果rs = stmt.executeQuery(sql);

更改为
语句stmt = dbConn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,为ResultSet.CONCUR_READ_ONLY);
结果rs = stmt.executeQuery(sql);

此时生成rs可以使用rs.first()反向移动指针操作