Как получить размер java.язык SQL.Объект ResultSet?
разве это не должна быть довольно простая операция? Тем не менее, я вижу, что нет ни size(), ни length() метод.
15 ответов
resultSet.last() следовал по resultSet.getRow() даст вам количество строк, но это может быть не очень хорошая идея, так как это может означать чтение всей таблицы по сети и выбрасывание данных. Сделай запрос.
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
}
Ну, если у вас есть ResultSet типа ResultSet.TYPE_FORWARD_ONLY вы хотите сохранить его таким образом (и не перейти к ResultSet.TYPE_SCROLL_INSENSITIVE или ResultSet.TYPE_SCROLL_INSENSITIVE для того, чтобы иметь возможность использовать .last()).
Я предлагаю очень хороший и эффективный Хак, где вы добавляете первую фиктивную/фальшивую строку вверху, содержащую количество строк.
пример
допустим, ваш запрос следующий
select MYBOOL,MYINT,MYCHAR,MYSMALLINT,MYVARCHAR
from MYTABLE
where ...blahblah...
и ваш вывод выглядит как
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]
просто рефакторинг кода, чтобы что-то вроде этого:
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);
ваш вывод запроса теперь будет чем-то вроде
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]
так что вам просто нужно
if(rs.next())
System.out.println("Recordcount: "+rs.getInt("RECORDCOUNT"));//hack: first record contains the record count
while(rs.next())
//do your stuff
я получил исключение при использовании rs.last()
if(rs.last()){
rowCount = rs.getRow();
rs.beforeFirst();
}
:
java.sql.SQLException: Invalid operation for forward only resultset
это связано с тем, что по умолчанию это ResultSet.TYPE_FORWARD_ONLY, что означает, что вы можете только использовать rs.next()
решение:
stmt=conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
Это простой способ сделать подсчет строк.
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
способ получения размера ResultSet, нет необходимости использовать ArrayList и т. д.
int size =0;
if (rs != null)
{
rs.beforeFirst();
rs.last();
size = rs.getRow();
}
теперь вы получите размер, и если вы хотите распечатать ResultSet, перед печатью используйте следующую строку кода тоже,
rs.beforeFirst();
[скорость рассмотрения]
много ppl здесь предлагает ResultSet.last() но для этого вам нужно открыть соединение как ResultSet.TYPE_SCROLL_INSENSITIVE который для базы данных Derby embedded составляет до 10 раз медленнее чем ResultSet.TYPE_FORWARD_ONLY.
согласно моим микро-тестам для встроенных баз данных Derby и H2 значительно быстрее вызывать SELECT COUNT(*) перед вашим выбором.
Я проверил значение времени выполнения ResultSet интерфейс и узнал, что это было в значительной степени ResultSetImpl все время. ResultSetImpl имеет метод под названием getUpdateCount() который возвращает значение, которое вы ищете.
этого примера кода должно быть достаточно:ResultSet resultSet = executeQuery(sqlQuery);double rowCount = ((ResultSetImpl)resultSet).getUpdateCount()
Я понимаю, что downcasting обычно является небезопасной процедурой, но этот метод еще не подвел меня.
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);
}
сегодня я использовал эту логику, почему я не знаю, как получить количество 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();
у меня была та же проблема. Используя ResultSet.first() таким образом, сразу после выполнения решил его:
if(rs.first()){
// Do your job
} else {
// No rows take some actions
}
документация (ссылке):
boolean first() throws SQLExceptionПеремещает курсор в первую строку в этом
ResultSet"объект".возвращает:
trueесли курсор находится на действительной гребите;falseесли в результирующем наборе нет строкБроски:
SQLException- если ошибка доступа к базе данных; этот метод вызывают на закрытом наборе результатов или тип результирующего набораTYPE_FORWARD_ONLY
SQLFeatureNotSupportedException- если драйвер JDBC не поддерживает этот методС:
1.2
дайте столбцу имя..
String query = "SELECT COUNT(*) as count FROM
ссылка на этот столбец из объекта ResultSet в int и сделайте свою логику оттуда..
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.");
}
}
подобно методу Гаррета,
boolean isEmpty = true
while(rs.next()){
isEmpty = false;
//do stuff here
}
приятно и просто, и у нас нет потенциально гигантского целого числа, генерируемого. Это, конечно, предполагает, что мы хотим повторить наш результирующий набор. Если мы не хотим перебирать его, то достаточно сделать подсчет.