Java ResultSet cómo verificar si hay resultados

311

Resultset no tiene ningún método para hasNext. Quiero verificar si el resultSet tiene algún valor

es esta la forma correcta

if (!resultSet.next() ) {
    System.out.println("no data");
} 
kal
fuente
2
Para futuros lectores como yo: las respuestas que me ayudaron son las de Felype y Dermot Doherty
Benj

Respuestas:

238

Eso es correcto, inicialmente el ResultSetcursor del 's apunta antes de la primera fila, si la primera llamada a next()retorna, falseentonces no había datos en el ResultSet.

Si usa este método, es posible que deba llamar beforeFirst()inmediatamente después para restablecerlo, ya que ahora se ha posicionado más allá de la primera fila.

Sin embargo, debe tenerse en cuenta que la respuesta de Seifer a continuación es una solución más elegante para esta pregunta.

novedoso
fuente
37
Pero tenga en cuenta que si hay / son / filas, después de esa prueba, estará apuntando a la primera fila. Así que asegúrese de no saltar una fila accidentalmente.
Matthew Flaschen
1
Buen punto de que el cursor (puntero) apunta a la primera fila
JohnMerlino
@MatthewFlaschen, tiene razón, para resolver el problema de omitir la primera fila, utilicé un do {...} while (rs.next);
Israelm
8
También puede llamar isBeforeFirst()para probar si hay filas devueltas sin avanzar el cursor, luego proceder normalmente.
SnakeDoc
528

Suponiendo que está trabajando con un recién devuelto ResultSetcuyo cursor apunta antes de la primera fila, una forma más fácil de verificar esto es simplemente llamar isBeforeFirst(). Esto evita tener que retroceder si los datos se van a leer.

Como se explica en la documentación , esto devuelve falso si el cursor no está antes del primer registro o si no hay filas en el ResultSet .

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

 

Seifer
fuente
15
Gracias, sí, lo sé, pero encontré el mismo problema y no estaba contento con la apariencia de avanzar para verificar y luego para leer. Pensé que esta solución más simple también beneficiaría a otros que están en la misma situación.
Seifer
55
Tenga en cuenta que, al menos para DB2, el conjunto de resultados debe ser del tipo "desplazable". Esto se puede configurar cuando crea la instrucción que se ejecutará.
Laurence Dougal Myers
1
La respuesta de Felype a continuación es más completa
Tom Howard
De la documentación de Oracle: Nota: El soporte para el método isBeforeFirst es opcional para ResultSets con un tipo de conjunto de resultados de TYPE_FORWARD_ONLY
emi-le
52

siempre puedes hacer lo siguiente por adelantado, y solo hacer una comprobación de bucle posterior

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

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

Usualmente harías algo como esto:

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

Si desea informar un conjunto vacío, agregue una variable que cuente los elementos leídos. Si solo necesita leer un solo elemento, entonces su código es adecuado.

kgiannakakis
fuente
16

Para estar totalmente seguro de que el conjunto de resultados está vacío o no, independientemente de la posición del cursor, haría algo como esto:

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

Esta función devolverá verdadero si ResultSet está vacío, falso si no, o arrojará una SQLException si ese ResultSet está cerrado / sin inicializar.

Felype
fuente
12

Es mejor usar ResultSet.next () junto con la sintaxis do {...} while () para esto.

La llamada "comprobar si hay resultados" ResultSet.next () mueve el cursor a la primera fila, así que use la sintaxis do {...} while () para procesar esa fila mientras continúa procesando las filas restantes devueltas por el bucle.

De esta manera, puede verificar los resultados, mientras que al mismo tiempo también procesa los resultados devueltos.

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
fuente
8

Según la respuesta más viable, la sugerencia es usar "isBeforeFirst ()". Esa no es la mejor solución si no tiene un "tipo de solo reenvío" .

Hay un método llamado " .first () ". Es menos exagerado obtener exactamente el mismo resultado. Verifica si hay algo en su "conjunto de resultados" y no avanza el cursor.

La documentación dice: "(...) falso si no hay filas en el conjunto de resultados ".

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

También puede simplemente llamar a isBeforeFirst () para probar si hay filas devueltas sin avanzar el cursor, luego proceder normalmente. - SnakeDoc Sep 2 '14 a las 19:00

Sin embargo, hay una diferencia entre "isBeforeFirst ()" y "first ()". Primero genera una excepción si se realiza en un conjunto de resultados del tipo "solo reenviar".

Compare las dos secciones de lanzamiento: 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 ()

De acuerdo, básicamente esto significa que debe usar "isBeforeFirst" siempre que tenga un tipo "solo reenvío". De lo contrario, es menos exagerado usar "first ()".

OddDev
fuente
1
¿Cómo es "menos exagerado" obtener exactamente el mismo resultado? Me parece que el propósito de first () es mover el cursor a la primera fila si aún no está allí (y devolver true si tuvo éxito). isBeforeFirst es una función puramente diagnóstica y parece más adecuada para los propósitos del autor. Además, la forma en que first () está redactado, devuelve verdadero siempre que esté "en una fila válida" ... lo cual es extraño ya que uno pensaría que estaría redactado como "en la primera fila". Para mí, no veo la ventaja de usar first () en este escenario a menos que su cursor haya avanzado y quiera volver al principio.
Jon
5

Eso funcionaría si desea ver si hay filas en el conjunto de resultados sí.

Tenga en cuenta que next()siempre se mueve a la siguiente fila, por lo que si planea leer el conjunto de resultados, debe tenerlo en cuenta.

El uso habitual con ResultSet (cuando simplemente se lee) es:

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

Lo que obviamente no funcionará correctamente si ya invocaste next()una vez para verificar si el conjunto de resultados estaba vacío, así que ten cuidado con eso. Aunque existen métodos para "realizar copias de seguridad", no son compatibles con todos los tipos de conjuntos de resultados.

Nuoji
fuente
5

Esta es una pieza práctica y fácil de leer, creo.

        if (res.next()) {
            do {

                // successfully in. do the right things.

            } while (res.next());
        } else {
           // no results back. warn the user.
        }
JSBach
fuente
2
if (!resultSet.isAfterLast() ) {    
System.out.println("No data"); 
} 

isAfterLast() también devuelve falso para el conjunto de resultados vacío, pero como el cursor está antes de la primera fila, este método parece más claro.

Nick Warke
fuente
2
if(resultSet.first) {

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

Porque si ResultSet no tiene raw, resultSet.firstdevuelve false.

usuario868927
fuente
Pero mueve el cursor a la primera fila innecesaria, y puede confundir el uso posterior del objeto ob "reset" y puede perder datos
Tigran Babajanyan
Aunque esto se ve mejor, no funcionará en un conjunto de resultados de cursor de solo avance.
eliteproxy
1

Lo mejor que puede hacer es verificar la primera fila para que cuando tenga la intención de obtener los datos pueda evitar el error de omitir una fila. Algo así como: if (! ResultSet.first ()) {System.out.println ("sin datos"); }

Anthony Oyovwe
fuente
1

Al usar resultSet.next () puede obtener fácilmente el resultado, ya sea que resultSet contenga algún valor o no

ResultSet resultSet = preparedStatement.executeQuery();
if(resultSet.next())
 //resultSet contain some values
else
 // empty resultSet
Ram72119
fuente
No repitas las respuestas existentes.
james.garriss
1
ResultSet result = stmt.executeQuery(sqlQuery);
if (!result.next())
    status = "ERROR";
else
    status = "SUCCESS";
Deepu Surendran
fuente
1

He estado intentando establecer la fila actual en el primer índice (que trata con las claves principales). Yo sugeriría

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

Cuando se llena ResultSet, apunta antes de la primera fila. Al establecerlo en la primera fila (indicado por rs.absolute(1)), devolverá verdadero indicando que se colocó con éxito en la fila 1, o falso si la fila no existe. Podemos extrapolar esto a

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

que establece la fila actual en la posición i y fallará si la fila no existe. Este es solo un método alternativo para

while(rs.next()){
    //Code
}
Andrés
fuente
¿Cual es tu respuesta?
CMedina
1

Creé el siguiente método para verificar si un ResultSet está vacío.

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

Es muy importante tener las siguientes consideraciones:

El objeto CallableStatement debe configurarse para permitir que el objeto ResultSet vaya al final y vuelva al principio.

TYPE_SCROLL_SENSITIVE : el objeto ResultSet puede desplazarse al final y volver al principio. Además puede atrapar los últimos cambios.

CONCUR_READ_ONLY : podemos leer los datos del objeto ResultSet, pero no podemos actualizarlos.

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

Creo que la forma más fácil de verificar el conjunto de resultados es a través de CollectionUtils en el paquete org.apache.commons.collections.CollectionUtils

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

Esto verificará la condición del conjunto de resultados nulo y vacío.

Para obtener más información detallada, puede consultar el siguiente documento. ColecciónUtils

Mitul Maheshwari
fuente
1
ResultSet no es una colección.
Joachim Lous
1

¿Por qué no usar 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

Para mí, marcar "if (rs.getRow ()! = 0)" parece funcionar bien.

stiebrs
fuente
0

puedes hacer algo como esto

boolean found = false;

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

if (!found)
    System.out.println("No Data");
Mohamed EL-Shabrawy
fuente
1
WAAAY demasiado complicado.
jordaniac89
0
ResultSet rs = rs.executeQuery();
if(rs.next())
{
  rs = rs.executeQuery();
  while(rs.next())
  {
    //do code part
  }
}
else
{
  //else if no result set
}

Es mejor volver a ejecutar la consulta porque cuando llamamos a la if(rs.next()){....}primera fila de ResultSet se ejecutará y después de esto while(rs.next()){....}, obtendremos el resultado de la siguiente línea. Así que creo que la re-ejecución de la consulta dentro ifes la mejor opción.

Arpit Trivedi
fuente
55
-1 Esta no es una mejor opción. ¿Por qué consultar la base de datos dos veces? ¿Qué pasa si los datos cambian drásticamente entre llamadas? Esto es un desperdicio.
Toby Caulk
-2

Inicialmente, el objeto del conjunto de resultados (rs) apunta al BFR (antes del primer registro). Una vez que usamos rs.next (), el cursor apunta al primer registro y el rs tiene "verdadero". Usando el bucle while puede imprimir todos los registros de la tabla. Después de recuperar todos los registros, el cursor se mueve a ALR (después del último registro) y se establecerá en nulo. Consideremos que hay 2 registros en la tabla.

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

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

En resumen, también podemos escribir la condición como while (rs.next ()).

Shiva
fuente
3
Su ciclo while no tendrá la oportunidad de operar en la primera fila devuelta, lo que parece un defecto algo fatal con este enfoque. Hay muchas sugerencias anteriores que son mejores que esta.
Julio