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ésultatsJette:
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 estTYPE_FORWARD_ONLY
SQLFeatureNotSupportedException
– si le pilote JDBC ne prend pas en charge cette méthodeDepuis:
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.