Java ResultSet如何检查是否有任何结果

354

Resultset没有hasNext方法。我想检查resultset是否有任何值。

这样做是否正确?

if (!resultSet.next() ) {
    System.out.println("no data");
} 

4
对于像我这样的未来读者:对我有帮助的答案是来自Felype和Dermot Doherty的答案。 - Benj
23个回答

596

假设您正在使用一个新返回的 ResultSet,其游标位于第一行之前,更简单的方法是调用 isBeforeFirst() 进行检查。这样可以避免在读取数据时需要回溯。

正如文档中所解释的,如果游标不在第一条记录之前或者 ResultSet 中没有记录,则返回 false。

if (!resultSet.isBeforeFirst() ) {    
    System.out.println("No data"); 
} 

 


15
谢谢,是的我知道,但我遇到了同样的问题,不喜欢前进检查然后向后阅读的外观。我认为这个更简单的解决方案会使其他处于相同情况的人受益。 - Seifer
8
请注意,至少对于DB2数据库而言,结果集必须是“可滚动”的类型。在创建要执行的语句时可以进行设置。 - Laurence Dougal Myers
3
Felype在下面的回答中提供的内容更加完整。 - Tom Howard
2
来自Oracle文档:注意:对于结果集类型为TYPE_FORWARD_ONLY的ResultSet,isBeforeFirst方法的支持是可选的。 - emi-le
我的结果集有一行,我还没有进行下一步操作,而isBeforeFirst仍然返回false。 - djg

263

没错,最初的ResultSet游标指向第一行之前,如果第一次调用next()返回falseResultSet中没有数据。

如果您使用此方法,则可能需要立即调用beforeFirst()进行重置,因为它现在已经定位到第一行之后了。

需要注意的是,下面Seifer的答案是这个问题的更加优雅的解决方案。


38
请注意,如果存在行,那么在这个测试之后,你会指向第一行。因此,请确保不要意外地跳过一行。 - Matthew Flaschen
1
光标(指针)指向第一行是一个很好的点。 - JohnMerlino
@MatthewFlaschen,你说得对,为了解决跳过第一行的问题,我使用了 do { ... } while (rs.next);。 - Israelm
9
你可以直接调用isBeforeFirst()方法来测试是否有行返回,而不需要移动游标,然后继续正常操作。 - SnakeDoc

58

你可以提前执行下一个操作,并在后续循环中进行检查。

if (!resultSet.next() ) {
    System.out.println("no data");
} else {

    do {
     //statement(s)
    } while (resultSet.next());
}

25

为了彻底确定结果集是否为空,而不考虑光标位置,我会这样做:

public static boolean isMyResultSetEmpty(ResultSet rs) throws SQLException {
    return (!rs.isBeforeFirst() && rs.getRow() == 0);
}

如果ResultSet为空,此函数将返回true;如果不为空,则返回false;如果ResultSet已关闭/未初始化,则抛出SQLException异常。


21

通常你会这样做:

while ( resultSet.next() ) { 
   // Read the next item
   resultSet.getString("columnName");
}

如果您想报告一个空集合,请添加一个计数读取的项目的变量。如果您只需要读取单个项目,则您的代码已经足够。


15

在这种情况下,最好使用ResultSet.next()与do {...} while()语法一起使用。

"检查是否有结果"调用ResultSet.next()将游标移动到第一行,因此使用do {...} while()语法来处理该行,同时继续处理循环返回的其余行。

这样您既可以检查任何结果,同时还可以处理返回的任何结果。

if(resultSet.next()) { // Checks for any results and moves cursor to first row,
    do { // Use 'do...while' to process the first row, while continuing to process remaining rows

    } while (resultSet.next());
}

9
根据最可行的答案,建议使用 "isBeforeFirst()"。如果没有 "forward only type",那么这不是最佳解决方案。

有一个名为 ".first()" 的方法。它更简单,可以得到完全相同的结果。您可以检查您的 "resultset" 是否有内容,而不需要移动光标。

文档说明:“(...) 如果结果集中没有行,则为 false”。

if(rs.first()){
    //do stuff      
}

您还可以调用isBeforeFirst()方法来测试是否有任何行返回而不推进光标,然后正常进行。但是,“isBeforeFirst()”和“first()”之间存在区别。如果在类型为“仅向前”的结果集上执行“first”,则会生成异常。请比较两个throw部分:http://docs.oracle.com/javase/7/docs/api/java/sql/ResultSet.html#isBeforeFirst() http://docs.oracle.com/javase/7/docs/api/java/sql/ResultSet.html#first()。基本上这意味着,只要您具有“仅向前”类型,就应该使用“isBeforeFirst”,否则使用“first()”会更少。

1
获取完全相同的结果如何“不那么过度”?在我看来,first() 的目的是将光标移动到第一行(如果尚未到达第一行),并在成功时返回 true。isBeforeFirst 是一个纯诊断函数,似乎更适合作者的目的。此外,first() 的措辞方式返回 true 只要它“在有效行上”...这很奇怪,因为人们会认为它应该被措辞为“在第一行上”。对我来说,在这种情况下使用 first() 没有优势,除非您的光标已经前进并且您想将其带回开头。 - Jon

5

如果您想查看结果集中是否有任何行,则可以使用该方法。

请注意,next() 总是移动到下一行,因此如果您计划从结果集中读取任何内容,则需要考虑这一点。

ResultSet 的通常用法(仅进行阅读)是:

while (resultSet.next())
{
   ... read from the row here ...
}

如果您已经调用了next()来检查结果集是否为空,那么这显然不会正常工作,所以要小心。虽然有一些“备份”的方法,但并不支持所有类型的结果集。


5
我认为这是一篇实用且易读的文章。
        if (res.next()) {
            do {

                // successfully in. do the right things.

            } while (res.next());
        } else {
           // no results back. warn the user.
        }

3
为什么不使用rs.getRow()呢?
int getRow()
           throws SQLException
Retrieves the current row number. The first row is number 1, the second number 2, and so on.
Note:Support for the getRow method is optional for ResultSets with a result set type of TYPE_FORWARD_ONLY

Returns:
the current row number; 0 if there is no current row
Throws:
SQLException - if a database access error occurs or this method is called on a closed result set
SQLFeatureNotSupportedException - if the JDBC driver does not support this method
Since:
1.2

对我来说,检查 "if (rs.getRow() != 0)" 看起来完全正常。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接