结果集:异常:设置类型为 TYPE_FORWARD_ONLY - 为什么?

发布于 2024-11-16 05:00:49 字数 1515 浏览 4 评论 0原文

我有非常简单的代码:

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)

是什么导致了这个问题以及如何修复它?

I have very simple code:

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

But when execute this code I am getting...

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)

What is causing this and how can I fix it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

丿*梦醉红颜 2024-11-23 05:00:50

rowCount 变量不是必需的。您正在 rs 上执行两个循环。只需第二个循环即可获取这部分代码完成的行数:

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

the rowCount variable is not necessary . you are performing two loops on the rs . only the second loop is necessary to get the number of rows which is done by this part of code:

 while (rs.next()){
 typeID=rs.getInt(1); //typeID is the number of rows in the ResultSet
}
萌能量女王 2024-11-23 05:00:50

Java 8 文档 声明如下:

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

   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

The Java 8 documentation states the following:

A default ResultSet object is not updatable and has a cursor that moves forward only. Thus, you can iterate through it only once and only from the first row to the last row. It is possible to produce ResultSet objects that are scrollable and/or updatable. The following code fragment, in which con is a valid Connection object, illustrates how to make a result set that is scrollable and insensitive to updates by others, and that is updatable. See ResultSet fields for other options.

   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
廻憶裏菂餘溫 2024-11-23 05:00:49

将您的第一个语句更改为这样

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

您可以向前和向后移动,所以不用担心的事情

Change your first statement to this

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

This way you can move forward and backward, so less things to worry about

很糊涂小朋友 2024-11-23 05:00:49

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

The type TYPE_FORWARD_ONLY means you can only move forward on the result set, not backward, so you get an exception when you try to go back with beforeFirst(). Instead you can either use the following prepareStatement(), which receives the resultset type as a parameter, or to do:

        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);
        }
撑一把青伞 2024-11-23 05:00:49

虽然这个问题很老,但答案不会过时,今天遇到了类似的问题,这就是我的处理方法,如

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()进行反向移动指针操作

Though this question is old, answers do not age, encountered a similar problem today, this is how I approached it, as here
This is the functionality provided by Java JDBC driver, and PostgreSQL database.
This case create a Statement object using the default parameters, the system-generated data sets can only be a one-way move the pointer forward, and not two-way mobile data record pointer, the former

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

Changed to
Statement stmt = dbConn.createStatement (ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
Result rs = stmt.executeQuery (sql);

Generated at this time rs can use rs.first () reverse move the pointer operation

哆兒滾 2024-11-23 05:00:49

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

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

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

You can only do this with a resultset that is of type TYPE_SCROLL_SENSITIVE, which is defined as "The constant indicating the type for a ResultSet object that is scrollable and generally sensitive to changes made by others."

You need to do something like the following ...

Statement statement = 
 connection.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
    ResultSet.CONCUR_READ_ONLY);
违心° 2024-11-23 05:00:49

java.sql.SQLException: JDBC 2.0 API 的结果集类型

为 TYPE_FORWARD_ONLY,用户可以灵活地向前或向后移动光标。

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

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

java.sql.SQLException: Result set type is TYPE_FORWARD_ONLY

with JDBC 2.0 API, the user has the flexibility to move the cursor either forward or backward.

Your error can be removed by creating the statemnt as follows

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

Also, a better way to count the number of rows would be

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
桃酥萝莉 2024-11-23 05:00:49

就像例外所说:除了向前之外,您不能以任何其他方向滚动结果集。因此,当您循环访问结果集以获取行数时(我什至不明白为什么这样做),那么该行将抛出该异常:

rs.beforeFirst();

因为这会向后滚动。

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

Like the exception says: You can't scroll your result set in any other direction than forwards. So when you loop through your result set to get the row count (I don't even understand why you do it), then this row will throw that exception:

rs.beforeFirst();

because that would scroll backwards.

Either create your statement so that you can scroll it (Google for examples) or remove that row counting. I'd suggest the latter, since the count seems unnecessary.

泪眸﹌ 2024-11-23 05:00:49

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

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

,而不是 ResultSet.TYPE_SCROLL_SENSITIVE

我会使用 INSENSITIVE 检查 此链接供参考

This question is pretty old. I believe the solution would already have been found. However, i would like to suggest here something different from what Aditya did.

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

Instead of ResultSet.TYPE_SCROLL_SENSITIVE, i would use INSENSITIVE

Check this link for refernce

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文