ResultSet:异常:set type是TYPE_FORWARD_ONLY - 为什么?

时间:2011-06-16 06:03:05

标签: java sql resultset jdbc-odbc

我的代码非常简单:

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)

造成这种情况的原因是什么?如何解决?

9 个答案:

答案 0 :(得分:18)

将您的第一个陈述更改为此

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

这样你可以前进和后退,所以不用担心

答案 1 :(得分:14)

类型 TYPE_FORWARD_ONLY 表示您只能向前移动结果集,而不是向后移动,因此当您尝试返回beforeFirst()时会出现异常。相反,您可以使用以下prepareStatement(),它接收结果集类型作为参数,或者执行:

        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);
        }

答案 2 :(得分:7)

只能使用类型为TYPE_SCROLL_SENSITIVE的结果集执行此操作,该结果集定义为“常量,指示可滚动且通常对其他人所做更改敏感的ResultSet对象的类型。”

您需要执行以下操作...

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

答案 3 :(得分:6)

虽然这个问题已经过时了,但答案并没有老化,今天遇到了类似的问题,这就是我接触它的方式,here 这是Java JDBC驱动程序和PostgreSQL数据库提供的功能。 这种情况下使用默认参数创建一个Statement对象,系统生成的数据集只能单向移动指针前进,而不是双向移动数据记录指针,前者

< / p>

Statement stmt = dbConn.createStatement();
结果rs = stmt.executeQuery(sql);

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

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

答案 4 :(得分:3)

就像异常所说的那样:你不能在任何其他方向滚动结果集而不是向前滚动。因此,当您遍历结果集以获取行计数时(我甚至不理解您为什么这样做),那么此行将抛出该异常:

rs.beforeFirst();

因为那会向后滚动。

创建语句以便您可以滚动它(例如Google)或删除该行计数。我建议使用后者,因为计数似乎没必要。

答案 5 :(得分: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

答案 6 :(得分:2)

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

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

我将使用INSENSITIVE

而不是ResultSet.TYPE_SCROLL_SENSITIVE

Check this link for refernce

答案 7 :(得分:0)

不需要rowCount变量。你在rs上执行两个循环。只需要第二个循环来获得这部分代码完成的行数:

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

答案 8 :(得分:0)

Java 8 documentation指出以下内容:

默认的ResultSet对象是不可更新的,并且具有仅向前移动的光标。因此,您只能遍历一次,并且只能从第一行到最后一行进行迭代。可以产生可滚动和/或可更新的ResultSet对象。下面的代码片段(其中con是有效的Connection对象)说明了如何制作可滚动且对其他人的更新不敏感并且可更新的结果集。有关其他选项,请参见ResultSet字段。

   Statement stmt = con.createStatement(
                                  ResultSet.TYPE_SCROLL_INSENSITIVE,
                                  ResultSet.CONCUR_UPDATABLE);
   ResultSet rs = stmt.executeQuery("SELECT a, b FROM TABLE2");
   // rs will be scrollable, will not show changes made by others,
   // and will be updatable