2010-04-07 5 views
21

Comment vérifier si resultset a une ligne ou plus avec JDBC?Comment vérifier si resultset a une ligne ou plus?

+0

Ceci est en effet quelque chose qui manque dans JDBC, raison pour laquelle ce n'est pas tout le système de base de données suppo Obtenir la taille du résultat à l'avance (parce que les résultats ne sont pas préchargés). Malheureusement, cela signifie que vous ne pouvez pas facilement utiliser ces fonctionnalités dans les bases de données qui le supportent, comme MySQL. – Thirler

+0

duplication possible de [Java ResultSet comment vérifier s'il y a des résultats] (http://stackoverflow.com/questions/867194/java-resultset-how-to-check-if-there-are-any-results) – rogerdpack

Répondre

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

Vous n'avez pas demandé celui-ci, mais vous pourriez en avoir besoin:

boolean isEmpty = ! rs.first(); 

Normalement, on n'a pas besoin du nombre de lignes parce que nous utilisons une boucle while pour parcourir le jeu de résultats au lieu d'une boucle 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); 
} 

Cependant, dans certains cas, vous voudrez peut-être à la fenêtre des résultats, et vous avez besoin du dossier compte à l'avance pour afficher à l'utilisateur quelque chose comme Row 1 to 10 of 100. Vous pouvez d'abord faire une requête distincte avec SELECT COUNT(*), pour obtenir le nombre d'enregistrements, mais notez que le nombre n'est qu'approximatif, car des lignes peuvent être ajoutées ou supprimées entre le délai d'exécution des deux requêtes.

Echantillon de ResultSet Overview

+0

le isMoreThanOneRow me donne l'erreur, L'opération demandée n'est pas supportée sur les ensembles de résultats seulement vers l'avant. –

+0

@ Vodo-SioskBaas, vous devez le faire juste après l'instruction 'executeQuery', de sorte que' first() 'n'a pas besoin de rembobiner ou de changer votre curseur pour qu'il puisse revenir en arrière. –

0

Ma suggestion sans complication: Récupérez la première ligne de résultat, puis essayez d'aller chercher la suivante. Si la tentative réussit, vous avez plusieurs lignes.

S'il y a plusieurs lignes et que vous souhaitez traiter ces données, vous devez mettre en cache les données de la première ligne ou utiliser un jeu de résultats déroulant pour revenir en haut avant de passer Les resultats.

Vous pouvez également demander directement à SQL cette information en faisant SELECT COUNT(*) sur le reste de votre requête; le résultat sera 0, 1 ou plus en fonction du nombre de lignes renvoyées par le reste de la requête. C'est assez facile à implémenter mais implique deux requêtes à la base de données, en supposant que vous allez vouloir lire et traiter la requête réelle suivante.

1

Il y a beaucoup d'options, et puisque vous ne fournissez pas plus contexte, la seule chose qui reste est de deviner. Mes réponses sont triées par ordre croissant de complexité et de performance.

  1. Exécutez simplement select count(1) FROM ... et obtenez la réponse. Vous devez exécuter une autre requête qui sélectionne et renvoie les données.
  2. itérez avec rs.next() et comptez jusqu'à ce que vous soyez satisfait. Ensuite, si vous avez toujours besoin des données réelles, réexécutez la même requête.
  3. Si votre pilote prend en charge l'itération arrière, optez pour rs.next() deux fois, puis revenez en arrière avec rs.previous().
+2

Si votre pilote ne prend pas en charge l'itération vers l'arrière, 'first()' commence généralement par recommencer. –

1

Vous n'avez pas besoin de JDBC pour cela. L'idiome normal consiste à collecter tous les résultats dans une collection et à utiliser les méthodes de collecte, telles que 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! 
} 

où le regard de la méthode list() comme quelque chose:

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

Ce n'est pas très bien. Que faire si le jeu de résultats contient des millions de lignes? – mindas

+0

@mindas: Cela n'aurait donc aucun sens de les 'SELECT * FROM table'. Vous avez besoin de 'SELECT COUNT (*) FROM table' alors. JDBC n'est simplement pas le bon outil pour ce but particulier et c'est exactement la raison pour laquelle une méthode 'ResultSet # size()' fictive n'existe pas dans JDBC. – BalusC

+0

La question initiale n'a jamais dit qu'il fait 'SELECT * FROM table' ni je l'ai suggéré. La question initiale n'a pas supposé que toutes les données sont réellement nécessaires. – mindas

-4

Obtenez le nombre de lignes en utilisant ResultSetMetaData classe.

A partir de votre code u peut créer ResultSetMetaData comme:

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

-1 ResultSetMetaData n'a rien à voir avec le nombre de lignes .. rsmd.getColumnCount() vous donne le nombre de colonnes de votre resultset – bluish

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

Pourquoi descend-il le vote, s'il vous plaît faites savoir le problème, car le code fonctionne –

0

Si vous voulez vous assurer qu'il ya exactement une ligne, vous pouvez vous assurer que la première ligne est la dernière :

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.  
    // .. 
} 
Questions connexes