java.sql.SQLException:ResultSet.type_FORWARD_ONLY类型的结果集不允许执行



所以我有一个这样的代码:

public static void ispisiSvakuDruguKnjigu(){
try{
Connection conn = getConnection();
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("select * from knjiga");
while(true){
if(rs.next()){
System.out.println(rs.getString("id")+" "+rs.getString("naslov"));
rs.relative(2);
} else {
return;
}
}
} catch (Exception e){
e.printStackTrace();
}
}

我们在一个从MySQL数据库中每隔两本书读取一次的类中所做的,它在我正在观看的类上正常工作,但在我的PC上,它向我显示了这样的错误:

java.sql.SQLException: Operation not allowed for a result set of type ResultSet.TYPE_FORWARD_ONLY.

EDIT首先,我要感谢大家的帮助,我是一个学习较晚的Java初学者。我已经成功地测试了它,并修复了代码,使其能够根据您的anwser按预期工作。我的困惑主要来自于我观看的课程和我的代码完全相同,它对他们有效,而不必做我所做的。再次感谢大家的耐心,并对大家的困惑表示歉意。

我改了这个:

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

这就是阅读JAVADOC 的代价

boolean relative​(int rows)
...
SQLException - if a database access error occurs; this method is called 
on a closed result set or the result set type is TYPE_FORWARD_ONLY
...
Since:
1.2

理论上,任何结果集都可以向后、向前、开始、结束和任何位置。至少,它有实现这一切的方法。

不幸的是,实际上"交付"这个承诺的功能是昂贵的。事实上,这太贵了,以至于你可以告诉ResultSet,你希望它违背这些承诺,转而节省内存等等。

这就是这里发生的事情:你有一个只向前的结果集。在导航到行的所有方法中,只有.next()可以正常工作,所有其他方法都会抛出该异常。

这有点奇怪,因为relative(1)的意思是";向前移动1行";,这与next()的功能完全相同,但是,next()可以工作并保证工作,并且任何JDBC驱动程序都可以在relative(1)上失败。

然而,从你写问题的方式来看,你似乎没有意识到.relative(1).next()在意义上是相同的(只是在实践中不相同,因为有些配置中.next()正常工作,而relative(1)抛出

因此,最有可能的解决方法是:重新阅读文档,熟悉这些方法的作用;你以前一定误解了。

但是,如果你只是在玩(要明确的是,.relative(1)应该永远不要写.next()是你应该写的方式),仅仅为了学习的目的,你有两个选择:

  1. 将ResultSet配置为完全可导航。这通常被称为"可滚动结果集"。con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, "theSql")会这么做。不过,我不建议这样做——通常只需编写代码,这样就不需要滚动了。

  2. 只需致电.next()即可。

TYPE_FORWARD_ONLY意味着您只能在结果集上向前移动,而不能向后移动,因此当您尝试返回beforeFirst()时会出现异常。尝试使用prepareStatement(),如下所示:

pstat=con.prepareStatement("select * from knjiga");             
rs=pstat.executeQuery();
int rowCount=0;
while(rs.next())
{
System.out.println(rs.getString("id")+" "+rs.getString("naslov"));

}