Czy nie powinna to być dość prosta operacja? Widzę jednak, że nie ma metody size()nor length().
Czy nie powinna to być dość prosta operacja? Widzę jednak, że nie ma metody size()nor length().
Odpowiedzi:
SELECT COUNT(*) FROM ...Zamiast tego wykonaj zapytanie.
LUB
int size =0;
if (rs != null)
{
rs.last(); // moves cursor to the last row
size = rs.getRow(); // get row id
}
W obu przypadkach nie będziesz musiał zapętlać całych danych.
select count?
ResultSet#last()nie działa na wszystkich typach ResultSetobiektów, musisz upewnić się, że używasz jednego z nich ResultSet.TYPE_SCROLL_INSENSITIVElubResultSet.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()działa dla TYPE_FORWARD_ONLYResultSets i beforeFirst()zgłasza dla nich błędy. Czy więc ta odpowiedź nie jest błędna?
ps=conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
Cóż, jeśli masz ResultSettypu ResultSet.TYPE_FORWARD_ONLYchcesz zachować to w ten sposób (i nie przełączyć się na ResultSet.TYPE_SCROLL_INSENSITIVElub ResultSet.TYPE_SCROLL_INSENSITIVEw celu umożliwienia użytkowania .last()).
Sugeruję bardzo fajny i wydajny hack, w którym dodajesz pierwszy fałszywy / fałszywy wiersz na górze zawierający liczbę wierszy.
Przykład
Powiedzmy, że twoje zapytanie jest następujące
select MYBOOL,MYINT,MYCHAR,MYSMALLINT,MYVARCHAR
from MYTABLE
where ...blahblah...
a twój wygląd wygląda
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]
Po prostu popraw kod na coś takiego:
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);
Dane wyjściowe zapytania będą teraz podobne
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]
Musisz po prostu
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++;
}
Mam wyjątek podczas używania rs.last()
if(rs.last()){
rowCount = rs.getRow();
rs.beforeFirst();
}
:
java.sql.SQLException: Invalid operation for forward only resultset
jest to spowodowane domyślnie ResultSet.TYPE_FORWARD_ONLY, co oznacza, że możesz używać tylkors.next()
rozwiązaniem jest:
stmt=conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
ResultSet.TYPE_FORWARD_ONLYna ResultSet.TYPE_SCROLL_INSENSITIVEogół pociąga za sobą w wielkim spadku wydajności.
SELECT COUNT(*) FROM default_tblwcześniej SELECT COUNT(*) FROM default_tbl, zajęło to mniej niż 1,5 sekundy. Testowałem na wbudowanej bazie danych derby 10.11.1.1
Sposób uzyskania rozmiaru ResultSet, nie ma potrzeby używania ArrayList itp
int size =0;
if (rs != null)
{
rs.beforeFirst();
rs.last();
size = rs.getRow();
}
Teraz otrzymasz rozmiar, a jeśli chcesz wydrukować zestaw wyników, przed wydrukowaniem użyj również następującego wiersza kodu,
rs.beforeFirst();
[Uwzględnienie prędkości]
Wiele ppl tutaj sugeruje, ResultSet.last()ale do tego trzeba by otworzyć połączenie, ponieważ ResultSet.TYPE_SCROLL_INSENSITIVEdla wbudowanej bazy danych Derby jest do 10 razy wolniejsze niż ResultSet.TYPE_FORWARD_ONLY.
Według moich mikrotestów dla osadzonych baz danych Derby i H2 znacznie szybciej jest zadzwonić SELECT COUNT(*)przed SELECT.
Jest to prosty sposób na liczenie wierszy.
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);
Sprawdziłem wartość środowiska uruchomieniowego interfejsu ResultSet i odkryłem, że przez cały czas była to w zasadzie ResultSetImpl . ResultSetImpl ma wywoływaną metodę, getUpdateCount()która zwraca poszukiwaną wartość.
Ten przykładowy kod powinien wystarczyć:
ResultSet resultSet = executeQuery(sqlQuery);
double rowCount = ((ResultSetImpl)resultSet).getUpdateCount()
Zdaję sobie sprawę, że downcasting jest ogólnie niebezpieczną procedurą, ale ta metoda jeszcze mnie nie zawiodła.
java.lang.ClassCastException: org.apache.tomcat.dbcp.dbcp.DelegatingResultSet cannot be cast to com.mysql.jdbc.ResultSetImpl
Dzisiaj użyłem tej logiki, dlaczego nie wiem, jak uzyskać liczbę 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();
Miałem ten sam problem. Używając ResultSet.first()w ten sposób zaraz po rozwiązaniu wykonania:
if(rs.first()){
// Do your job
} else {
// No rows take some actions
}
Dokumentacja ( link ):
boolean first() throws SQLExceptionPrzenosi kursor do pierwszego wiersza w tym
ResultSetobiekcie.Zwroty:
truejeśli kursor znajduje się w poprawnym wierszu;falsejeśli nie ma wierszy w zestawie wynikówRzuty:
SQLException- jeśli wystąpi błąd dostępu do bazy danych; ta metoda jest wywoływana dla zamkniętego zestawu wyników lub typem zestawu wyników jestTYPE_FORWARD_ONLY
SQLFeatureNotSupportedException- jeśli sterownik JDBC nie obsługuje tej metodyOd:
1.2
Najłatwiejsze podejście, zapytanie Run Count (*), wykonaj resultSet.next (), aby wskazać pierwszy wiersz, a następnie po prostu wykonaj wynikSet.getString (1), aby uzyskać liczbę. Kod :
ResultSet rs = statement.executeQuery("Select Count(*) from your_db");
if(rs.next()) {
int count = rs.getString(1).toInt()
}
Nadaj kolumnie nazwę…
String query = "SELECT COUNT(*) as count FROM
Odwołaj się do tej kolumny z obiektu ResultSet do int i wykonaj swoją logikę stamtąd.
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.");
}
}