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

sAa*_*aNu 13 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);
}
Run Code Online (Sandbox Code Playgroud)

但是当执行这段代码时我得到了......

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)
Run Code Online (Sandbox Code Playgroud)

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

小智 18

将您的第一个声明更改为此

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

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


MBy*_*ByD 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);
        }
Run Code Online (Sandbox Code Playgroud)


Sai*_*Sai 7

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

你需要做以下的事......

Statement statement = 
 connection.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
    ResultSet.CONCUR_READ_ONLY);
Run Code Online (Sandbox Code Playgroud)


小智 6

java.sql.SQLException:结果集类型为 TYPE_FORWARD_ONLY

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

您可以通过创建如下语句来删除您的错误

Statement st = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY);
Run Code Online (Sandbox Code Playgroud)

另外,计算行数的更好方法是

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
Run Code Online (Sandbox Code Playgroud)


小智 6

尽管这个问题很陈旧,答案没有老化,但是今天遇到了类似的问题,这就是我的解决方法,因为这里 是Java JDBC驱动程序和PostgreSQL数据库提供的功能。这种情况下使用默认参数创建一个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()反向移动指针操作