Cela ne devrait-il pas être une opération assez simple? Cependant, je vois qu'il n'y a size()
ni length()
méthode ni .
Cela ne devrait-il pas être une opération assez simple? Cependant, je vois qu'il n'y a size()
ni length()
méthode ni .
Réponses:
Faites SELECT COUNT(*) FROM ...
plutôt une requête.
OU
int size =0;
if (rs != null)
{
rs.last(); // moves cursor to the last row
size = rs.getRow(); // get row id
}
Dans les deux cas, vous n'aurez pas à parcourir toutes les données.
select count
?
ResultSet#last()
ne fonctionne pas sur tous les types d' ResultSet
objets, vous devez vous assurer d' utiliser celui qui est soit ResultSet.TYPE_SCROLL_INSENSITIVE
ouResultSet.TYPE_SCROLL_SENSITIVE
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
}
getRow()
fonctionne pour TYPE_FORWARD_ONLY
ResultSets et beforeFirst()
génère des erreurs pour ceux-ci. Cette réponse n'est-elle pas défectueuse alors?
ps=conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
Eh bien, si vous avez un ResultSet
type, ResultSet.TYPE_FORWARD_ONLY
vous devez le conserver de cette façon (et ne pas passer à un ResultSet.TYPE_SCROLL_INSENSITIVE
ou ResultSet.TYPE_SCROLL_INSENSITIVE
pour pouvoir l'utiliser .last()
).
Je suggère un hack très agréable et efficace, où vous ajoutez une première ligne fausse / 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]
Réorganisez simplement votre code en quelque chose comme ceci:
Statement s=myConnection.createStatement(ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_READ_ONLY);
String 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);
La sortie de votre 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 vous 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
ResultSet.TYPE_FORWARD_ONLY
)
int i = 0;
while(rs.next()) {
i++;
}
J'ai une exception lors de l'utilisation rs.last()
if(rs.last()){
rowCount = rs.getRow();
rs.beforeFirst();
}
:
java.sql.SQLException: Invalid operation for forward only resultset
c'est dû par défaut à ce qu'il est ResultSet.TYPE_FORWARD_ONLY
, ce qui signifie que vous ne pouvez utiliser quers.next()
la solution est:
stmt=conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
ResultSet.TYPE_FORWARD_ONLY
à ResultSet.TYPE_SCROLL_INSENSITIVE
entraîne généralement une énorme pénalité de performance.
SELECT COUNT(*) FROM default_tbl
avant, SELECT COUNT(*) FROM default_tbl
il a fallu au total moins de 1,5 seconde. J'ai testé sur la base de données derby intégrée 10.11.1.1
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 une connexion ResultSet.TYPE_SCROLL_INSENSITIVE
qui, pour la base de données intégrée Derby, est jusqu'à 10 fois plus lente queResultSet.TYPE_FORWARD_ONLY
.
Selon mes micro-tests pour les bases de données Derby et H2 intégrées, il est beaucoup plus rapide d'appeler SELECT COUNT(*)
avant votre SELECT.
C'est un moyen simple de compter les 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
String sql = "select count(*) from message";
ps = cn.prepareStatement(sql);
rs = ps.executeQuery();
int rowCount = 0;
while(rs.next()) {
rowCount = Integer.parseInt(rs.getString("count(*)"));
System.out.println(Integer.parseInt(rs.getString("count(*)")));
}
System.out.println("Count : " + rowCount);
J'ai vérifié la valeur d'exécution de l' interface ResultSet et j'ai découvert que c'était à peu près tout le temps un ResultSetImpl . ResultSetImpl a une méthode appeléegetUpdateCount()
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 le downcasting est généralement une procédure dangereuse mais cette méthode ne m'a pas encore échoué.
java.lang.ClassCastException: org.apache.tomcat.dbcp.dbcp.DelegatingResultSet cannot be cast to com.mysql.jdbc.ResultSetImpl
Aujourd'hui, j'ai utilisé cette logique pourquoi je ne sais pas obtenir 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. L'utilisation ResultSet.first()
de cette manière juste après l'exécution l'a résolu:
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
ResultSet
objet.Retour:
true
si le curseur se trouve sur une ligne valide;false
s'il n'y a pas de lignes dans le jeu de résultatsJette:
SQLException
- si une erreur d'accès à la base de données 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éthodePuisque:
1.2
Approche la plus simple, exécutez la requête Count (*), effectuez resultSet.next () pour pointer vers la première ligne, puis effectuez simplement resultSet.getString (1) pour obtenir le nombre. Code:
ResultSet rs = statement.executeQuery("Select Count(*) from your_db");
if(rs.next()) {
int count = rs.getString(1).toInt()
}
Donnez un nom à la colonne ..
String query = "SELECT COUNT(*) as count FROM
Référencez cette colonne de l'objet ResultSet dans un int et faites votre logique à partir de là.
PreparedStatement statement = connection.prepareStatement(query);
statement.setString(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.");
}
}