Как получить размер java.sql.ResultSet?

Разве это не должно быть довольно простой операцией? Тем не менее, я вижу, что нет ни size(), ни length() метод.

вопрос задан 10.10.2008
Jake
6671 репутация

15 ответов


  • 239 рейтинг

    resultSet.last(), за которым следует resultSet.getRow(), подсчитает количество строк, но это может быть плохой идеей, так как это может означать чтение всей таблицы по сети и удаление данных. Вместо этого выполните SELECT COUNT(*) FROM ... запрос.

    ответ дан finnw, с репутацией 37503, 10.10.2008
  • 78 рейтинг
    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
    }
    
    ответ дан JeeBee, с репутацией 15617, 10.10.2008
  • 17 рейтинг

    Хорошо, если у вас есть 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
    
    ответ дан Unai Vivi, с репутацией 2327, 10.04.2013
  • 12 рейтинг
    int i = 0;
    while(rs.next()) {
        i++;
    }
    
    ответ дан bhaskar, с репутацией 129, 18.04.2014
  • 9 рейтинг

    Я получил исключение при использовании 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); 
    
    ответ дан Dan, с репутацией 865, 28.11.2012
  • 4 рейтинг

    Это простой способ подсчета строк.

    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
    
    ответ дан CounterSpell, с репутацией 105, 30.09.2012
  • 3 рейтинг

    [Скорость рассмотрения]

    Лота здесь предлагает ResultSet.last(), но для этого вам нужно будет открыть соединение как ResultSet.TYPE_SCROLL_INSENSITIVE, которое для встроенной базы данных Derby в 10 раз больше МЕДЛЕННЫХ , чем ResultSet.TYPE_FORWARD_ONLY.

    Согласно моим микротестам для встроенных баз данных Derby и H2, намного быстрее позвонить по номеру SELECT COUNT(*) до вашего SELECT.

    Вот более подробно мой код и мои тесты

    ответ дан Vit Bernatik, с репутацией 1467, 21.05.2015
  • 3 рейтинг

    Способ получения размера ResultSet, нет необходимости использовать ArrayList и т. Д.

    int size =0;  
    if (rs != null)   
    {  
    rs.beforeFirst();  
     rs.last();  
    size = rs.getRow();
    }
    

    Теперь Вы получите размер, и если вы хотите напечатать ResultSet, перед печатью используйте следующую строку кода,

    rs.beforeFirst();  
    
    ответ дан Anptk, с репутацией 1056, 28.08.2014
  • 1 рейтинг
            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);
    
         }
    
    ответ дан Peter.Chu, с репутацией 115, 27.08.2013
  • 1 рейтинг

    Я проверил значение времени выполнения интерфейса 3894676001 ResultSet и обнаружил, что это был в значительной степени ResultSetImpl все время. ResultSetImpl имеет метод с именем getUpdateCount(), который возвращает искомое значение.

    Этого примера кода должно хватить:
    ResultSet resultSet = executeQuery(sqlQuery);
    double rowCount = ((ResultSetImpl)resultSet).getUpdateCount()

    Я понимаю, что даункатинг, как правило, небезопасная процедура, но этот метод еще не подвел меня.

    ответ дан clausavram, с репутацией 188, 2.06.2013
  • 1 рейтинг

    Сегодня я использовал эту логику, почему не знаю, как получить счетчик 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.
    
    ответ дан parksangdonews, с репутацией 11, 6.11.2017
  • 0 рейтинг
    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();
    
    ответ дан Ben, с репутацией 9, 13.03.2013
  • 0 рейтинг

    Дайте столбцу имя. ,

    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.");
        }
    }
    
    ответ дан ReMaX, с репутацией 1, 11.05.2018
  • 0 рейтинг

    У меня была такая же проблема. Используя 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

    ответ дан Israel Hernández, с репутацией 1, 6.11.2014
  • -3 рейтинг

    Аналогично методу Гаррета,

    boolean isEmpty = true
    while(rs.next()){
        isEmpty = false;
        //do stuff here
    }
    

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

    ответ дан Adam Traub, с репутацией 1, 13.06.2016