353

Resultset has no method for hasNext. I want to check if the resultSet has any value

is this the correct way

if (!resultSet.next() ) {
    System.out.println("no data");
} 
kal
  • 28,545
  • 49
  • 129
  • 149
  • 4
    For future readers like me : answers that helped me are those from Felype and Dermot Doherty – Benj Oct 31 '19 at 13:35

23 Answers23

594

Assuming you are working with a newly returned ResultSet whose cursor is pointing before the first row, an easier way to check this is to just call isBeforeFirst(). This avoids having to back-track if the data is to be read.

As explained in the documentation, this returns false if the cursor is not before the first record or if there are no rows in the ResultSet.

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

 

Thorbjørn Ravn Andersen
  • 73,784
  • 33
  • 194
  • 347
Seifer
  • 5,957
  • 2
  • 14
  • 3
  • 15
    Thanks, yes I know but I encountered the same problem and wasn't happy with the look of moving forward to check then backward to read. I thought this simplier solution would benefit others who are in the same situation as well. – Seifer Jul 26 '11 at 04:03
  • 8
    Note that, at least for DB2, the result set has to be a "scrollable" type. This can be set when you create the statement to be executed. – Laurence Dougal Myers Sep 04 '13 at 07:53
  • 3
    [Felype's answer below](https://stackoverflow.com/a/15750832/269221) is more complete – Tom Howard Aug 09 '17 at 21:47
  • 2
    From the Oracle Documentation: _Note:Support for the isBeforeFirst method is optional for ResultSets with a result set type of TYPE_FORWARD_ONLY_ – emi-le Mar 28 '19 at 18:22
  • My resultset has a row, I haven't nexted it, and isBeforeFirst still returns false – djg Sep 16 '22 at 08:26
263

That's correct, initially the ResultSet's cursor is pointing to before the first row, if the first call to next() returns false then there was no data in the ResultSet.

If you use this method, you may have to call beforeFirst() immediately after to reset it, since it has positioned itself past the first row now.

It should be noted however, that Seifer's answer below is a more elegant solution to this question.

Community
  • 1
  • 1
ninesided
  • 23,085
  • 14
  • 83
  • 107
  • 38
    But keep in mind, if there /are/ rows, after that test you will be pointing to the first row. So make sure you don't accidentally skip a row. – Matthew Flaschen May 15 '09 at 06:15
  • 1
    Good point that the cursor (pointer) is pointing at the first row – JohnMerlino Jun 11 '14 at 16:21
  • @MatthewFlaschen, you're right, to solve the issue of skip the first row, i used a do { ... } while (rs.next); – Israelm Jul 22 '14 at 19:19
  • 9
    You can also just call `isBeforeFirst()` to test if there are any rows returned without advancing the cursor, then proceed normally. – SnakeDoc Sep 02 '14 at 19:00
58

you could always do the next up front, and just do a post loop check

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

    do {
     //statement(s)
    } while (resultSet.next());
}
Maslow
  • 18,464
  • 20
  • 106
  • 193
25

To be totally sure of rather the resultset is empty or not regardless of cursor position, I would do something like this:

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

This function will return true if ResultSet is empty, false if not or throw an SQLException if that ResultSet is closed/uninitialized.

Allwin
  • 41
  • 7
Felype
  • 3,087
  • 2
  • 25
  • 36
21

You would usually do something like this:

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

If you want to report an empty set, add a variable counting the items read. If you only need to read a single item, then your code is adequate.

kgiannakakis
  • 103,016
  • 27
  • 158
  • 194
15

Best to use ResultSet.next() along with the do {...} while() syntax for this.

The "check for any results" call ResultSet.next() moves the cursor to the first row, so use the do {...} while() syntax to process that row while continuing to process remaining rows returned by the loop.

This way you get to check for any results, while at the same time also processing any results returned.

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());
}
Dermot Doherty
  • 500
  • 5
  • 6
9

According to the most viable answer the suggestion is to use "isBeforeFirst()". That's not the best solution if you don't have a "forward only type".

There's a method called ".first()". It's less overkill to get the exact same result. You check whether there is something in your "resultset" and don't advance your cursor.

The documentation states: "(...) false if there are no rows in the result set".

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

You can also just call isBeforeFirst() to test if there are any rows returned without advancing the cursor, then proceed normally. – SnakeDoc Sep 2 '14 at 19:00

However, there's a difference between "isBeforeFirst()" and "first()". First generates an exception if done on a resultset from type "forward only".

Compare the two throw sections: 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()

Okay, basically this means that you should use "isBeforeFirst" as long as you have a "forward only" type. Otherwise it's less overkill to use "first()".

OddDev
  • 3,644
  • 5
  • 30
  • 53
  • 1
    How is it "less overkill" to get the exact same result? It seems to me the purpose of first() is to move the cursor to the first row if it's not already there (and return true if it succeeded). isBeforeFirst is a purely diagnostic function only and seems more suited toward author's purposes. Plus, the way first() is worded, it returns true as long as it's "on a valid row"... which is odd as one would think it would be worded as "on the first row". To me, I don't see the advantage of using first() in this scenario unless your cursor has advanced and you want to bring it back to the beginning. – Jon Apr 07 '17 at 20:53
5

This is a practical and easy read piece I believe.

        if (res.next()) {
            do {

                // successfully in. do the right things.

            } while (res.next());
        } else {
           // no results back. warn the user.
        }
JSBach
  • 447
  • 1
  • 6
  • 13
5

That would work if you want to see if there are any rows in the result set yes.

Note that next() always moves to the next row, so if you are planning on doing any reading from the result set you need to take that into account.

Usual usage with ResultSet (when simply reading) is:

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

Which obviously won't work correctly if you invoked next() once already to check if the result set was empty, so watch out for that. Although there are methods for "backing up", they are not supported for all types of result sets.

Nuoji
  • 3,438
  • 2
  • 21
  • 35
3
if (!resultSet.isAfterLast() ) {    
System.out.println("No data"); 
} 

isAfterLast() also returns false for empty result set but since cursor is before first row anyways, this method seems more clear.

Nick Warke
  • 91
  • 6
3

Why not use 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

For me check "if (rs.getRow() != 0)" seems to work just fine.

stiebrs
  • 379
  • 3
  • 13
2
if(resultSet.first) {

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

Because if ResultSet has no raw then resultSet.first returns false.

Shinoy Shaji
  • 397
  • 10
  • 27
user868927
  • 31
  • 1
1
ResultSet result = stmt.executeQuery(sqlQuery);
if (!result.next())
    status = "ERROR";
else
    status = "SUCCESS";
Tom
  • 16,842
  • 17
  • 45
  • 54
Deepu Surendran
  • 205
  • 2
  • 3
1

The best thing for to do is to check the first row so that when you intend to get the data you can avoid the mistake of skipping a row. Something like: if (!resultSet.first() ) { System.out.println("no data"); }

1

By using resultSet.next() you can easily get the result, whether resultSet containing any value or not

ResultSet resultSet = preparedStatement.executeQuery();
if(resultSet.next())
 //resultSet contain some values
else
 // empty resultSet
Lucas Zamboulis
  • 2,494
  • 5
  • 24
  • 27
Ram72119
  • 107
  • 18
1

I've been attempting to set the current row to the first index (dealing with primary keys). I would suggest

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

When the ResultSet is populated, it points to before the first row. When setting it to the first row (indicated by rs.absolute(1)) it will return true denoting it was successfully placed at row 1, or false if the row does not exist. We can extrapolate this to

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

which sets the current row to position i and will fail if the row doesn't exist. This is just an alternative method to

while(rs.next()){
    //Code
}
Andrew
  • 11
  • 3
1

I created the following method to check if a ResultSet is empty.

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

It is very important to have the following considerations:

CallableStatement object must be setted to let to ResultSet object go at the end and go back to top.

TYPE_SCROLL_SENSITIVE: ResultSet object can shift at the end and go back to top. Further can catch last changes.

CONCUR_READ_ONLY: We can read the ResultSet object data, but can not updated.

CallableStatement proc = dbconex.prepareCall(select, ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
Cristian
  • 548
  • 6
  • 8
1

I think the easiest way for checking result set is via CollectionUtils under package org.apache.commons.collections.CollectionUtils

if(CollectionUtils.isNotEmpty(resultList)){
  /**
  * do some stuff
  */
}

This will check for null as well as empty result set condition.

For more detail information you can refer to the following doc. CollectionUtils

Mitul Maheshwari
  • 2,647
  • 4
  • 24
  • 38
0

you can do something like this

boolean found = false;

while ( resultSet.next() )
{
    found = true;
    resultSet.getString("column_name");
}

if (!found)
    System.out.println("No Data");
0
ResultSet rs = rs.executeQuery();
if(rs.next())
{
  rs = rs.executeQuery();
  while(rs.next())
  {
    //do code part
  }
}
else
{
  //else if no result set
}

It is better to re execute query because when we call if(rs.next()){....} first row of ResultSet will be executed and after it inside while(rs.next()){....} we'll get result from next line. So I think re-execution of query inside if is the better option.

EWit
  • 1,954
  • 13
  • 22
  • 19
Arpit Trivedi
  • 97
  • 3
  • 12
  • 5
    -1 This is not a better option. Why query the database twice? What if data changes drastically between calls? This is wasteful. – Toby Caulk Aug 18 '15 at 19:24
0
if (resultSet==null ) {
    System.out.println("no data");
}
0

A word of caution,

if you are using the org.springframework.jdbc.core.RowMapper be very careful how you are checking that your ResultSet is empty since the following holds true for the mapRow method:

This method should not call next() on the ResultSet; it is only supposed to map values of the current row. <- from the documentation

In this situation, your check can become something along the lines of

resultSet.beforeFirst();
if (!resultSet.next() ) {
    System.out.println("no data");
} 
Konstantin Grigorov
  • 1,356
  • 12
  • 20
-2

Initially, the result set object (rs) points to the BFR (before first record). Once we use rs.next(), the cursor points to the first record and the rs holds "true". Using the while loop you can print all the records of the table. After all the records are retrieved, the cursor moves to ALR (After last record) and it will be set to null. Let us consider that there are 2 records in the table.

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

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

In short hand, we can also write the condition as while (rs.next()).

Shiva
  • 47
  • 2
  • 3
    Your while loop will not get a chance to operate on the first row returned, which seems a somewhat fatal flaw with this approach. There are plenty of suggestions above that are better than this one. – Jules May 20 '14 at 17:04