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


311

结果集没有hasNext的方法。我想检查一下resultSet是否有任何值

这是正确的方法吗

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

2
对于像我这样的未来读者:那些帮助我的答案来自Felype和Dermot Doherty
Benj,

Answers:


237

没错,最初ResultSet的光标指向第一行之前,如果第一次调用next()return false,则没有数据ResultSet

如果使用此方法,beforeFirst()则由于它现在已定位在第一行之后,因此可能必须在复位后立即调用。

但是,应该注意的是,塞弗的以下回答是对该问题的更优雅的解决方案。


37
但是请记住,如果有/ are /行,那么在测试之后,您将指向第一行。因此,请确保您不会意外跳过一行。
马修·弗拉申

1
光标(指针)指向第一行的好点
JohnMerlino 2014年

@MatthewFlaschen,您是对的,为了解决跳过第一行的问题,我使用了do {...} while(rs.next);
Israelm

8
您也可以调用isBeforeFirst()来测试是否有返回的行而不前进光标,然后正常进行。
SnakeDoc 2014年

528

假设您正在使用一个新返回ResultSet的指针指向第一行之前的光标,一种更简单的检查方法是调用isBeforeFirst()。如果要读取数据,这避免了必须回溯。

如文档中所述,如果光标不在第一条记录之前,或者ResultSet中没有行,则返回false 。

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

 


15
谢谢,是的,我知道,但是我遇到了同样的问题,对向前查看然后向后阅读很不满意。我认为这种简单的解决方案也会使处于相同情况的其他人受益。
塞弗

5
注意,至少对于DB2,结果集必须是“可滚动”类型。您可以在创建要执行的语句时进行设置。
Laurence Dougal Myers 2013年


来自Oracle文档:注意:对于结果集类型为TYPE_FORWARD_ONLY的ResultSet,对isBeforeFirst方法的支持是可选的
emi-le

52

您总是可以预先做下一个,然后进行循环后检查

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

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

21

您通常会执行以下操作:

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

如果要报告一个空集,请添加一个变量,以计算读取的项目。如果您只需要阅读一个项目,那么您的代码就足够了。


16

为了完全确定结果集是否为空或与光标位置无关,我将执行以下操作:

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

如果ResultSet为空,则此函数将返回true;否则,则返回false;如果关闭/未初始化该ResultSet,则将引发SQLException。


12

最好将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());
}

8

根据最可行的答案,建议是使用“ isBeforeFirst()”。如果您没有“仅转发类型”,那不是最佳解决方案

有一种称为“ .first() ”的方法。获得完全相同的结果就不会太矫kill过正。您检查“结果集”中是否有内容,并且不要使光标前进。

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

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

您也可以只调用isBeforeFirst()来测试是否有返回的行而不前进光标,然后正常进行。– SnakeDoc 2014年9月2日19:00

但是,“ isBeforeFirst()”和“ first()”之间是有区别的。如果对“仅转发”类型的结果集进行处理,则首先会生成异常。

比较两个抛出部分: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.
        }

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

isAfterLast() 对于空结果集也返回false,但是由于游标始终位于第一行之前,因此此方法似乎更清晰。


2
if(resultSet.first) {

} else { 
    system.out.println("No raw or resultSet is empty");
}

因为如果ResultSet没有原始值,则resultSet.first返回false。


但是它将光标移动到第一行是不必要的,并且可能使ob“重置”对象的进一步使用变得混乱,并且可能会丢失数据
Tigran Babajanyan

尽管这看起来更好,但它不适用于仅向前的游标结果集。
eliteproxy

1

最好的做法是检查第一行,以便在打算获取数据时可以避免跳过行的错误。类似于:if(!resultSet.first()){System.out.println(“ no data”); }


1

通过使用resultSet.next(),无论resultSet是否包含任何值,您都可以轻松获取结果

ResultSet resultSet = preparedStatement.executeQuery();
if(resultSet.next())
 //resultSet contain some values
else
 // empty resultSet

不要重复现有的答案。
james.garriss 2015年

1
ResultSet result = stmt.executeQuery(sqlQuery);
if (!result.next())
    status = "ERROR";
else
    status = "SUCCESS";

1

我一直试图将当前行设置为第一个索引(使用主键)。我会建议

if(rs.absolute(1)){
    System.out.println("We have data");
} else {
    System.out.println("No data");
}

填充ResultSet时,它指向第一行之前。将其设置为第一行(由表示rs.absolute(1))时,它将返回true,表示已成功将其放置在第1行;如果该行不存在,则返回false。我们可以推断为

for(int i=1; rs.absolute(i); i++){
    //Code
}

这会将当前行设置为位置i,如果该行不存在,则失败。这只是替代方法

while(rs.next()){
    //Code
}

你的答案是什么?
CMedina '16

1

我创建了以下方法来检查ResultSet是否为空。

public static boolean resultSetIsEmpty(ResultSet rs){        
    try {
        // We point the last row
        rs.last();
        int rsRows=rs.getRow(); // get last row number

        if (rsRows == 0) {
            return true;
        }

        // It is necessary to back to top the pointer, so we can see all rows in our ResultSet object.
        rs.beforeFirst();
        return false;
    }catch(SQLException ex){            
        return true;
    }
}

有以下注意事项非常重要:

必须将CallableStatement对象设置为让ResultSet对象移到最后并回到顶部。

TYPE_SCROLL_SENSITIVE:ResultSet对象可以在末尾移动并返回顶部。进一步可以捕捉到最后的变化。

CONCUR_READ_ONLY:我们可以读取ResultSet对象的数据,但是不能更新。

CallableStatement proc = dbconex.prepareCall(select, ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);


1

为什么不使用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)”似乎很好。



0
ResultSet rs = rs.executeQuery();
if(rs.next())
{
  rs = rs.executeQuery();
  while(rs.next())
  {
    //do code part
  }
}
else
{
  //else if no result set
}

最好重新执行查询,因为当我们调用if(rs.next()){....}ResultSet的第一行时,将在其中执行之后,while(rs.next()){....}从下一行获取结果。因此,我认为重新执行内部查询if是更好的选择。


5
-1这不是一个更好的选择。为什么要查询数据库两次?如果两次呼叫之间数据发生巨大变化怎么办?这很浪费。
Toby Caulk 2015年

-2

最初,结果集对象(rs)指向BFR(在第一条记录之前)。一旦我们使用rs.next(),光标将指向第一条记录,而rs则保持“ true”。使用while循环,您可以打印表的所有记录。检索所有记录后,光标将移至ALR(最后一条记录之后),并将其设置为null。让我们考虑表中有2条记录。

if(rs.next()==false){
    // there are no records found
    }    

while (rs.next()==true){
    // print all the records of the table
    }

简而言之,我们也可以将条件写为while(rs.next())。


3
您的while循环将没有机会在返回的第一行进行操作,这种方法似乎有些致命的缺陷。上面有很多建议都比这更好。
Jules 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.