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.
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 .
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á.
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
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.
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());}
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".
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 ()".
¿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.
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.
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"); }
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
Creé el siguiente método para verificar si un ResultSet está vacío.
publicstaticboolean resultSetIsEmpty(ResultSet rs){try{// We point the last row
rs.last();int rsRows=rs.getRow();// get last row numberif(rsRows ==0){returntrue;}// It is necessary to back to top the pointer, so we can see all rows in our ResultSet object.
rs.beforeFirst();returnfalse;}catch(SQLException ex){returntrue;}}
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.
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
int getRow()throwsSQLExceptionRetrieves the current row number.The first row is number 1, the second number 2, and so on.Note:Supportfor the getRow method is optional forResultSets with a result set type of TYPE_FORWARD_ONLY
Returns:
the current row number;0if 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
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.
-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 ()).
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.
Respuestas:
Eso es correcto, inicialmente el
ResultSet
cursor del 's apunta antes de la primera fila, si la primera llamada anext()
retorna,false
entonces no había datos en elResultSet
.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.
fuente
isBeforeFirst()
para probar si hay filas devueltas sin avanzar el cursor, luego proceder normalmente.Suponiendo que está trabajando con un recién devuelto
ResultSet
cuyo cursor apunta antes de la primera fila, una forma más fácil de verificar esto es simplemente llamarisBeforeFirst()
. 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 .
fuente
siempre puedes hacer lo siguiente por adelantado, y solo hacer una comprobación de bucle posterior
fuente
Usualmente harías algo como esto:
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.
fuente
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:
Esta función devolverá verdadero si ResultSet está vacío, falso si no, o arrojará una SQLException si ese ResultSet está cerrado / sin inicializar.
fuente
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.
fuente
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 ".
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 ()".
fuente
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:
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.fuente
Esta es una pieza práctica y fácil de leer, creo.
fuente
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.fuente
Porque si ResultSet no tiene raw,
resultSet.first
devuelve false.fuente
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"); }
fuente
Al usar resultSet.next () puede obtener fácilmente el resultado, ya sea que resultSet contenga algún valor o no
fuente
fuente
He estado intentando establecer la fila actual en el primer índice (que trata con las claves principales). Yo sugeriría
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 aque establece la fila actual en la posición i y fallará si la fila no existe. Este es solo un método alternativo para
fuente
Creé el siguiente método para verificar si un ResultSet está vacío.
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.
fuente
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
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
fuente
¿Por qué no usar rs.getRow ()?
Para mí, marcar "if (rs.getRow ()! = 0)" parece funcionar bien.
fuente
puedes hacer algo como esto
fuente
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 estowhile(rs.next()){....}
, obtendremos el resultado de la siguiente línea. Así que creo que la re-ejecución de la consulta dentroif
es la mejor opción.fuente
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.
En resumen, también podemos escribir la condición como while (rs.next ()).
fuente