web-dev-qa-db-fra.com

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

Comment vérifier si les résultats ont une ligne ou plus avec JDBC?

22
TopCoder
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 pouvez en avoir besoin:

boolean isEmpty = ! rs.first();

Normalement, nous n'avons pas besoin du nombre de lignes car 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);
}

Toutefois, dans certains cas, vous pouvez souhaiter afficher les résultats et vous devez connaître le nombre d'enregistrements à l'avance pour que l'utilisateur puisse afficher quelque chose comme Row 1 to 10 of 100. Vous pouvez d'abord effectuer une requête distincte avec SELECT COUNT(*) pour obtenir le nombre d'enregistrements, mais notez que le nombre est approximatif, car des lignes peuvent être ajoutées ou supprimées entre le temps nécessaire à l'exécution des deux requêtes.

Exemple de Aperçu du jeu de résultats

28
Marcus Adams

Il existe de nombreuses options et, comme vous ne fournissez pas plus de contexte, il ne reste plus qu'à deviner. Mes réponses sont classées par complexité et ordre croissant de performances.

  1. Lancez 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 heureux. 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() plusieurs fois, puis rembobinez-le avec rs.previous().
1
mindas

Vous n'avez pas besoin de JDBC pour cela. L'idiome normal est de collecter tous les résultats d'une collection et d'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ù la méthode list() ressemble à 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;
}
1
BalusC

Ma suggestion simple: récupérez la première ligne de résultat, puis essayez d’extraire la suivante. Si la tentative aboutit, vous avez plusieurs lignes.

S'il existe plusieurs lignes et que vous souhaitez traiter ces données, vous devez soit mettre en cache les éléments de la première ligne, soit utiliser un jeu de résultats à défilement de manière à pouvoir revenir en haut avant de consulter les résultats.

Vous pouvez également demander directement ces informations à SQL en effectuant une 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 à mettre en œuvre, mais implique deux requêtes à la base de données, en supposant que vous souhaitiez lire et traiter la requête elle-même.

0
Carl Smotricz

Si vous voulez vous assurer qu'il y aexactementune 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.    
    // .. 
}
0
Garfield