Non dovrebbe essere un'operazione piuttosto semplice? Tuttavia, vedo che non esiste né un metodo size()né length().
Non dovrebbe essere un'operazione piuttosto semplice? Tuttavia, vedo che non esiste né un metodo size()né length().
Risposte:
SELECT COUNT(*) FROM ...Esegui invece una query.
O
int size =0;
if (rs != null)
{
rs.last(); // moves cursor to the last row
size = rs.getRow(); // get row id
}
In entrambi i casi, non sarà necessario eseguire il ciclo su tutti i dati.
select count?
ResultSet#last()non funziona su tutti i tipi di ResultSetoggetti, è necessario assicurarsi di utilizzarne uno che sia ResultSet.TYPE_SCROLL_INSENSITIVEoResultSet.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()funziona per i TYPE_FORWARD_ONLYResultSet e beforeFirst()genera errori per quelli. Questa risposta non è difettosa allora?
ps=conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
Bene, se hai un ResultSettipo ResultSet.TYPE_FORWARD_ONLY, vuoi mantenerlo in quel modo (e non passare a un ResultSet.TYPE_SCROLL_INSENSITIVEo ResultSet.TYPE_SCROLL_INSENSITIVEper poterlo usare .last()).
Suggerisco un hack molto bello ed efficiente, in cui aggiungi una prima riga fasulla / fasulla in alto contenente il numero di righe.
Esempio
Supponiamo che la tua query sia la seguente
select MYBOOL,MYINT,MYCHAR,MYSMALLINT,MYVARCHAR
from MYTABLE
where ...blahblah...
e il tuo output sembra
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]
Rifatti semplicemente il tuo codice su qualcosa del genere:
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);
L'output della query ora sarà simile
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]
Quindi devi solo
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++;
}
Ho ricevuto un'eccezione durante l'utilizzo rs.last()
if(rs.last()){
rowCount = rs.getRow();
rs.beforeFirst();
}
:
java.sql.SQLException: Invalid operation for forward only resultset
per impostazione predefinita è ResultSet.TYPE_FORWARD_ONLY, il che significa che è possibile utilizzare solors.next()
la soluzione è:
stmt=conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
ResultSet.TYPE_FORWARD_ONLYa di ResultSet.TYPE_SCROLL_INSENSITIVEsolito comporta una penalità di prestazione enorme .
SELECT COUNT(*) FROM default_tblprima SELECT COUNT(*) FROM default_tblci sono voluti complessivamente meno di 1,5 secondi. Ho testato il database derby incorporato 10.11.1.1
Il modo di ottenere dimensioni di ResultSet, Non è necessario utilizzare ArrayList ecc
int size =0;
if (rs != null)
{
rs.beforeFirst();
rs.last();
size = rs.getRow();
}
Ora otterrai le dimensioni e, se vuoi stampare il ResultSet, prima di stampare usa anche la seguente riga di codice,
rs.beforeFirst();
[Considerazione sulla velocità]
Molti ppl qui suggeriscono, ResultSet.last()ma per questo sarebbe necessario aprire la connessione in quanto ResultSet.TYPE_SCROLL_INSENSITIVEper il database incorporato Derby è fino a 10 volte più LENTO di ResultSet.TYPE_FORWARD_ONLY.
Secondo i miei micro-test per database Derby e H2 incorporati, è molto più veloce chiamare SELECT COUNT(*)prima di SELECT.
Ecco più in dettaglio il mio codice e i miei parametri di riferimento
È un modo semplice per eseguire il conteggio delle righe.
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);
Ho controllato il valore di runtime dell'interfaccia ResultSet e ho scoperto che era praticamente un ResultSetImpl per tutto il tempo. ResultSetImpl ha un metodo chiamato getUpdateCount()che restituisce il valore che stai cercando.
Questo esempio di codice dovrebbe essere sufficiente:
ResultSet resultSet = executeQuery(sqlQuery);
double rowCount = ((ResultSetImpl)resultSet).getUpdateCount()
Mi rendo conto che il downcasting è generalmente una procedura non sicura, ma questo metodo non mi ha ancora deluso.
java.lang.ClassCastException: org.apache.tomcat.dbcp.dbcp.DelegatingResultSet cannot be cast to com.mysql.jdbc.ResultSetImpl
Oggi ho usato questa logica perché non so come ottenere il conteggio di 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();
Avevo lo stesso problema. Utilizzando ResultSet.first()in questo modo subito dopo l'esecuzione risolto:
if(rs.first()){
// Do your job
} else {
// No rows take some actions
}
Documentazione ( link ):
boolean first() throws SQLExceptionSposta il cursore sulla prima riga di questo
ResultSetoggetto.Ritorna:
truese il cursore si trova su una riga valida;falsese non ci sono righe nel set di risultatiProduce:
SQLException- se si verifica un errore di accesso al database; questo metodo viene chiamato su un set di risultati chiuso o il tipo di set di risultati èTYPE_FORWARD_ONLY
SQLFeatureNotSupportedException- se il driver JDBC non supporta questo metodoDa:
1.2
Approccio più semplice, eseguire la query Count (*), eseguire resultSet.next () per puntare alla prima riga e quindi eseguire resultSet.getString (1) per ottenere il conteggio. Codice :
ResultSet rs = statement.executeQuery("Select Count(*) from your_db");
if(rs.next()) {
int count = rs.getString(1).toInt()
}
Dai un nome alla colonna ..
String query = "SELECT COUNT(*) as count FROM
Fai riferimento a quella colonna dall'oggetto ResultSet in un int e fai la tua logica da 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.");
}
}