2010-04-07 8 views
21

¿Cómo comprobar si el conjunto de resultados tiene una fila o más con JDBC?¿Cómo comprobar si el conjunto de resultados tiene una fila o más?

+0

Esto es de hecho algo que falta en JDBC, razón por la cual esto es que no todo el sistema de bases de datos suppo rt obtener el tamaño del conjunto de resultados por adelantado (porque los resultados no se captan previamente). Desafortunadamente, esto significa que no puede usar fácilmente esas funciones en bases de datos que sí lo admiten, como MySQL. – Thirler

+0

posible duplicado de [Java ResultSet cómo comprobar si hay ningún resultado] (http://stackoverflow.com/questions/867194/java-resultset-how-to-check-if-there-are-any-results) – rogerdpack

Respuesta

28
ResultSet rs = stmt.executeQuery("SELECT a, b, c FROM Table1"); 
boolean isMoreThanOneRow = rs.first() && rs.next(); 

Usted no pidió éste, pero que lo necesite:

boolean isEmpty = ! rs.first(); 

Normalmente, no es necesario el número de filas porque utilizamos un bucle while para recorrer el conjunto de resultados en lugar de un bucle FOR:

ResultSet rs = stmt.executeQuery("SELECT a, b, c FROM Table1"); 
while (rs.next()) { 
    // retrieve and print the values for the current row 
    int i = rs.getInt("a"); 
    String s = rs.getString("b"); 
    float f = rs.getFloat("c"); 
    System.out.println("ROW = " + i + " " + s + " " + f); 
} 

Sin embargo, en algunos casos, es posible que desee ventana de los resultados, y que necesita el número de registros antes de tiempo para mostrar al usuario algo así como Row 1 to 10 of 100. Puede hacer una consulta por separado con SELECT COUNT(*) primero, para obtener el recuento de registros, pero tenga en cuenta que el recuento es solo aproximado, ya que las filas se pueden agregar o eliminar entre el tiempo que lleva ejecutar las dos consultas.

muestra de la ResultSet Overview

+0

the isMoreThanOneRow me da el error. La operación solicitada no se admite en los conjuntos de resultados solo de reenvío. –

+0

@ Vodo-SioskBaas, que tiene que hacer que justo después de la declaración 'executeQuery', por lo que la primera'() 'no tiene que retroceder o cambiar el cursor de manera que pueda retroceder. –

0

Mi sugerencia obvia: Obtenga la primera fila de resultados, y luego intente buscar la siguiente. Si el intento es exitoso, tiene más de una fila.

Si hay más de una fila y desea procesar esa información, necesitará almacenarla en la primera fila o utilizar un conjunto de resultados desplazable para poder volver a la parte superior antes de pasar Los resultados.

También puede solicitar directamente a SQL esta información haciendo un SELECT COUNT(*) en el resto de su consulta; el resultado será 0, 1 o más dependiendo de cuántas filas devolverá el resto de la consulta. Es bastante fácil de implementar, pero implica dos consultas al DB, suponiendo que va a querer leer y procesar la consulta real a continuación.

1

Hay muchas opciones, y ya que no proporciona más contexto lo único que queda es adivinar. Mis respuestas están ordenadas por complejidad y rendimiento de orden ascendente.

  1. Simplemente ejecute select count(1) FROM ... y obtenga la respuesta. Tendría que ejecutar otra consulta que realmente selecciona y devuelve los datos.
  2. Itera con rs.next() y cuente hasta que esté satisfecho. Luego, si aún necesita los datos reales, vuelva a ejecutar la misma consulta.
  3. Si su controlador admite la iteración hacia atrás, vaya a rs.next() un par de veces y luego retroceda con rs.previous().
+2

Si su controlador no es compatible con la iteración hacia atrás, 'first()' generalmente funciona para comenzar de nuevo. –

1

No necesita JDBC para esto. La expresión normal es recopilar todos los resultados en una colección y hacer uso de los métodos de recopilación, como List#size().

List<Item> items = itemDAO.list(); 

if (items.isEmpty()) { 
    // It is empty! 
if (items.size() == 1) { 
    // It has only one row! 
} else { 
    // It has more than one row! 
} 

donde el aspecto list() método como algo:

public List<Item> list() throws SQLException { 
    Connection connection = null; 
    Statement statement = null; 
    ResultSet resultSet = null; 
    List<Item> items = new ArrayList<Item>(); 

    try { 
     connection = database.getConnection(); 
     statement = connection.createStatement(); 
     resultSet = statement.executeQuery(SQL_LIST); 
     while (resultSet.next()) { 
      Item item = new Item(); 
      item.setId(resultSet.getLong("id")); 
      item.setName(resultSet.getString("name")); 
      // ... 
      items.add(item); 
     } 
    } finally { 
     if (resultSet != null) try { resultSet.close(); } catch (SQLException logOrIgnore) {} 
     if (statement != null) try { statement.close(); } catch (SQLException logOrIgnore) {} 
     if (connection != null) try { connection.close(); } catch (SQLException logOrIgnore) {} 
    } 

    return items; 
} 
+0

Esto no se escala muy bien. ¿Qué pasa si el conjunto de resultados tiene millones de filas? – mindas

+0

@mindas: Entonces ya no tendría sentido 'SELECT * FROM table'. Necesitas 'SELECT COUNT (*) FROM table' luego. JDBC simplemente no es la herramienta adecuada para este propósito en particular y esa es exactamente la razón por la cual un método 'ResultSet # size()' ficticio no existe en JDBC. – BalusC

+0

La pregunta original nunca ha dicho que esté haciendo 'SELECT * FROM table' ni lo he sugerido. La pregunta original no tiene la suposición de que todos los datos son realmente necesarios también. – mindas

-4

obtener el recuento de fila utilizando ResultSetMetaData clase.

Desde su código u puede crear ResultSetMetaData como:

ResultSetMetaData rsmd = resultSet.getMetaData(); //get ResultSetMetaData 
rsmd.getColumnCount();  // get row count from resultsetmetadata 
+0

-1 ResultSetMetaData no tiene nada que ver con el número de filas .. rsmd.getColumnCount() le da el número de columnas de su conjunto de resultados – bluish

-1
public int rowCountValue(ResultSet rsValue) throws SQLException { 
    ResultSet rowCountValue = rsValue; 
    int countRow = 0; 
    while (rowCountValue.next()) { 
     countRow++; 
    } 
    return countRow; 
} 
+0

¿Por qué se está abajo votación, por favor, dar a conocer el problema, ya que el código funciona –

0

Si desea asegurarse de que no es exactamente una fila, se puede asegurar que la primera fila es la última :

ResultSet rs = stmt.executeQuery("SELECT a FROM Table1 WHERE b=10"); 
if (rs.isBeforeFirst() && rs.next() && rs.isFirst() && rs.isLast()) { 
    // Logic for where there's exactly 1 row 
    Long valA = rs.getLong("a");  
    // ... 
} 
else { 
    // More that one row or 0 rows returned.  
    // .. 
} 
Cuestiones relacionadas