Comment puis-je obtenir la taille d’un java.sql.ResultSet?

Cela ne devrait-il pas être une opération assez simple? Cependant, je vois qu’il n’y a pas de méthode size() ni length() .

resultSet.last() suivi de resultSet.getRow() vous donnera le nombre de lignes, mais ce n’est peut-être pas une bonne idée car cela peut signifier lire toute la table sur le réseau et jeter les données. Faites plutôt une requête SELECT COUNT(*) FROM ...

 ResultSet rs = ps.executeQuery(); int rowcount = 0; if (rs.last()) { rowcount = rs.getRow(); rs.beforeFirst(); // not rs.first() because the rs.next() below will move on, missing the first element } while (rs.next()) { // do your standard per row stuff } 

Eh bien, si vous avez un ResultSet de type ResultSet.TYPE_FORWARD_ONLY vous voulez le conserver de cette façon (et ne pas basculer vers ResultSet.TYPE_SCROLL_INSENSITIVE ou ResultSet.TYPE_SCROLL_INSENSITIVE pour pouvoir utiliser .last() ).

Je suggère un hack très agréable et efficace, où vous ajoutez une première ligne bidon / bidon en haut contenant le nombre de lignes.

Exemple

Disons que votre requête est la suivante

 select MYBOOL,MYINT,MYCHAR,MYSMALLINT,MYVARCHAR from MYTABLE where ...blahblah... 

et votre sortie ressemble à

 true 65537 "Hey" -32768 "The quick brown fox" false 123456 "Sup" 300 "The lazy dog" false -123123 "Yo" 0 "Go ahead and jump" false 3 "EVH" 456 "Might as well jump" ... [1000 total rows] 

Refactorez simplement votre code pour quelque chose comme ceci:

 Statement s=myConnection.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY); Ssortingng from_where="FROM myTable WHERE ...blahblah... "; //h4x ResultSet rs=s.executeQuery("select count(*)as RECORDCOUNT," + "cast(null as boolean)as MYBOOL," + "cast(null as int)as MYINT," + "cast(null as char(1))as MYCHAR," + "cast(null as smallint)as MYSMALLINT," + "cast(null as varchar(1))as MYVARCHAR " +from_where +"UNION ALL "//the "ALL" part prevents internal re-sorting to prevent duplicates (and we do not want that) +"select cast(null as int)as RECORDCOUNT," + "MYBOOL,MYINT,MYCHAR,MYSMALLINT,MYVARCHAR " +from_where); 

Votre résultat de requête sera maintenant quelque chose comme

 1000 null null null null null null true 65537 "Hey" -32768 "The quick brown fox" null false 123456 "Sup" 300 "The lazy dog" null false -123123 "Yo" 0 "Go ahead and jump" null false 3 "EVH" 456 "Might as well jump" ... [1001 total rows] 

Il suffit donc de

 if(rs.next()) System.out.println("Recordcount: "+rs.getInt("RECORDCOUNT"));//hack: first record contains the record count while(rs.next()) //do your stuff 
 int i = 0; while(rs.next()) { i++; } 

J’ai eu une exception lors de l’utilisation de rs.last()

 if(rs.last()){ rowCount = rs.getRow(); rs.beforeFirst(); } 

:

 java.sql.SQLException: Invalid operation for forward only resultset 

il est dû par défaut à ResultSet.TYPE_FORWARD_ONLY , ce qui signifie que vous ne pouvez utiliser que rs.next()

la solution est la suivante:

 stmt=conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); 

C’est un moyen simple de calculer le nombre de lignes.

 ResultSet rs = job.getSearchedResult(stmt); int rsCount = 0; //but notice that you'll only get correct ResultSet size after end of the while loop while(rs.next()) { //do your other per row stuff rsCount = rsCount + 1; }//end while 

La façon d’obtenir la taille de ResultSet, pas besoin d’utiliser ArrayList, etc.

 int size =0; if (rs != null) { rs.beforeFirst(); rs.last(); size = rs.getRow(); } 

Maintenant, vous obtiendrez la taille, Et si vous voulez imprimer le ResultSet, avant d’imprimer, utilisez également la ligne de code suivante,

 rs.beforeFirst(); 

[Considération de vitesse]

Beaucoup de ppl suggèrent ici ResultSet.last() mais pour cela vous devez ouvrir la connexion en tant que ResultSet.TYPE_SCROLL_INSENSITIVE qui pour la firebase database intégrée Derby est jusqu’à 10 fois plus SLOWER que ResultSet.TYPE_FORWARD_ONLY .

Selon mes micro-tests pour les bases de données embarquées Derby et H2, il est beaucoup plus rapide d’appeler SELECT COUNT(*) avant votre SELECT.

Voici plus en détail mon code et mes benchmarks

J’ai vérifié la valeur d’exécution de l’interface ResultSet et découvert qu’il s’agissait pratiquement d’un ResultSetImpl tout le temps. ResultSetImpl a une méthode appelée getUpdateCount() qui renvoie la valeur que vous recherchez.

Cet exemple de code devrait suffire:
ResultSet resultSet = executeQuery(sqlQuery);
double rowCount = ((ResultSetImpl)resultSet).getUpdateCount()

Je me rends compte que la baisse est généralement une procédure dangereuse mais cette méthode ne m’a pas encore échoué.

  Ssortingng sql = "select count(*) from message"; ps = cn.prepareStatement(sql); rs = ps.executeQuery(); int rowCount = 0; while(rs.next()) { rowCount = Integer.parseInt(rs.getSsortingng("count(*)")); System.out.println(Integer.parseInt(rs.getSsortingng("count(*)"))); } System.out.println("Count : " + rowCount); } 

Aujourd’hui, j’ai utilisé cette logique pour ne pas connaître le nombre de RS.

 int chkSize = 0; if (rs.next()) { do { ..... blah blah enter code here for each rs. chkSize++; } while (rs.next()); } else { enter code here for rs size = 0 } // good luck to u. 
 theStatement=theConnection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); ResultSet theResult=theStatement.executeQuery(query); //Get the size of the data returned theResult.last(); int size = theResult.getRow() * theResult.getMetaData().getColumnCount(); theResult.beforeFirst(); 

J’avais le même problème. En utilisant ResultSet.first() de cette façon juste après l’exécution, il a résolu le problème:

 if(rs.first()){ // Do your job } else { // No rows take some actions } 

Documentation ( lien ):

 boolean first() throws SQLException 

Déplace le curseur sur la première ligne de cet object ResultSet .

Résultats:

true si le curseur est sur une ligne valide; false s’il n’y a pas de ligne dans le jeu de résultats

Jette:

SQLException – si une erreur d’access à la firebase database se produit; cette méthode est appelée sur un jeu de résultats fermé ou le type de jeu de résultats est TYPE_FORWARD_ONLY

SQLFeatureNotSupportedException – si le pilote JDBC ne prend pas en charge cette méthode

Depuis:

1.2

Donnez un nom à la colonne.

 Ssortingng query = "SELECT COUNT(*) as count FROM 

Référencez cette colonne de l’object ResultSet dans un int et faites votre logique à partir de là.

 PreparedStatement statement = connection.prepareStatement(query); statement.setSsortingng(1, item.getProductId()); ResultSet resultSet = statement.executeQuery(); while (resultSet.next()) { int count = resultSet.getInt("count"); if (count >= 1) { System.out.println("Product ID already exists."); } else { System.out.println("New Product ID."); } } 

Semblable à la méthode de Garret,

 boolean isEmpty = true while(rs.next()){ isEmpty = false; //do stuff here } 

Sympa et simple, et nous n’avons pas un nombre entier potentiellement géant. Cela suppose bien sûr que nous voulions parcourir notre jeu de résultats. Si nous ne voulons pas itérer par-dessus, alors compter devrait suffire.