Как получить размер 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

int i = 0;
while(rs.next()) {
    i++;
}

я получил исключение при использовании 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
}

приятно и просто, и у нас нет потенциально гигантского целого числа, генерируемого. Это, конечно, предполагает, что мы хотим повторить наш результирующий набор. Если мы не хотим перебирать его, то достаточно сделать подсчет.