Как получить количество строк с помощью ResultSet в Java?


Я пытаюсь создать простой метод, который получает набор данных в качестве параметра и возвращает целое число, содержащее количество строк в ResultSet. Это правильный способ сделать это или не так много?

int size = 0;
    try {
        while(rs.next()){
            size++;
        }
    }
    catch(Exception ex) {
        System.out.println("------------------Tablerize.getRowCount-----------------");
        System.out.println("Cannot get resultSet row count: " + ex);
        System.out.println("--------------------------------------------------------");
    }

Я попытался это:

int size = 0;
try {
    resultSet.last();
    size = resultSet.getRow();
    resultSet.beforeFirst();
}
catch(Exception ex) {
    return 0;
}
return size;

но я получил сообщение об ошибкеcom.microsoft.sqlserver.jdbc.SQLServerException: The requested operation is not supported on forward only result sets.

заранее спасибо за указатели!

13 57

13 ответов:

Если у вас есть доступ к подготовленному оператору, который приводит к этому набору результатов, вы можете использовать

connection.prepareStatement(sql, 
  ResultSet.TYPE_SCROLL_INSENSITIVE, 
  ResultSet.CONCUR_READ_ONLY);

это подготовит заявление таким образом, что вы можете перемотать курсор. Это также задокументировано в ResultSet Javadoc

в целом, однако, переадресация и перемотка курсоров могут быть довольно неэффективными для больших результирующих наборов. Другой вариант в SQL Server - вычислить общее количество строк непосредственно в SQL заявление:

SELECT my_table.*, count(*) over () total_rows
FROM my_table
WHERE ...

ваш SQL оператор создания кода может быть как

statement = connection.createStatement();

чтобы решить " com.Microsoft.от SQLServer.интерфейс jdbc.SQLServerException: запрошенная операция не поддерживается только для пересылки результирующих наборов " исключение изменить выше кода с

statement = connection.createStatement(
    ResultSet.TYPE_SCROLL_INSENSITIVE, 
    ResultSet.CONCUR_READ_ONLY);

после вышеуказанного изменения вы можете использовать

int size = 0;
try {
    resultSet.last();
    size = resultSet.getRow();
    resultSet.beforeFirst();
}
catch(Exception ex) {
    return 0;
}
return size;

получить количество строк

Statement s = cd.createStatement();
ResultSet r = s.executeQuery("SELECT COUNT(*) AS rowcount FROM FieldMaster");
r.next();
int count = r.getInt("rowcount");
r.close();
System.out.println("MyTable has " + count + " row(s).");

иногда JDBC не поддерживает следующий метод дает ошибку, как "TYPE_FORWARD_ONLY" использовать это решение

Sqlite не поддерживает в JDBC.

resultSet.last();
size = resultSet.getRow();
resultSet.beforeFirst();

поэтому в то время используйте это решение.

спасибо..

Do a запрос.

Я только что сделал метод getter.

public int getNumberRows(){
    try{
       statement = connection.creatStatement();
       resultset = statement.executeQuery("your query here");
       if(resultset.last()){
          return resultset.getRow();
       } else {
           return 0; //just cus I like to always do some kinda else statement.
       }
    } catch (Exception e){
       System.out.println("Error getting row count");
       e.printStackTrace();
    }
    return 0;
}

ваша функция вернет размер результирующего набора, но его курсор будет установлен после последней записи, поэтому без перемотки его путем вызова beforeFirst (), first() или previous() вы не сможете прочитать его строки, а методы перемотки не будут работать только с прямым набором результатов (вы получите то же исключение, которое вы получаете во втором фрагменте кода).

большинство водителей поддерживают только набор результатов - таким способом, как последние, beforeFirst и т. д. не поддерживаются.

первый подход подходит, если вы также получаете данные в том же цикле - в противном случае результирующий набор уже был повторен и не может быть использован снова.

в большинстве случаев требование состоит в том, чтобы получить количество строк, которые запрос вернет без извлечения строк. Итерация по результирующему набору для поиска количества строк почти такая же, как и обработка данные. Вместо этого лучше сделать другой запрос count (*).

другие уже ответили, как решить вашу проблему, поэтому я не буду повторять то, что уже было сказано, но я скажу следующее: Вы, вероятно, должны найти способ решить свои проблемы, не зная счет набора результатов до прочтения результатов.

существует очень мало обстоятельств, когда количество строк действительно необходимо до чтения результирующего набора, особенно на таком языке, как Java. Единственный случай, когда я думаю о том, где количество строк будет необходимо, - это когда количество строк-это единственные данные, которые вам нужны (в этом случае запрос count будет выше). В противном случае лучше использовать объект-оболочку для представления данных таблицы и хранить эти объекты в динамическом контейнере, таком как ArrayList. Затем, как только результирующий набор был повторен, вы можете получить счетчик списка массивов. Для каждого решения, которое требует знания количества строк перед чтением результирующего набора, вы, вероятно, можете придумать решение, которое делает это, не зная количества строк перед чтением без особых усилий. Думая о решениях, которые обходят необходимость знать количество строк перед обработкой, вы сохраняете ResultSet проблему прокрутки до конца результирующего набора, а затем обратно в начало (что может быть очень дорогой операцией для больших результирующих наборов).

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

просто хотел предложить свои 2 цента на эту тему.

Если у вас есть таблица и сохранение идентификатора в качестве основного и автоматического приращения, то это будет работать

пример кода для получения общего количества строкhttp://www.java2s.com/Tutorial/Java/0340__Database/GettheNumberofRowsinaDatabaseTable.htm

Ниже приведен код

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.Statement;

public class Main {
  public static void main(String[] args) throws Exception {
    Connection conn = getConnection();
    Statement st = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
        ResultSet.CONCUR_UPDATABLE);

    st.executeUpdate("create table survey (id int,name varchar(30));");
    st.executeUpdate("insert into survey (id,name ) values (1,'nameValue')");
    st.executeUpdate("insert into survey (id,name ) values (2,null)");
    st.executeUpdate("insert into survey (id,name ) values (3,'Tom')");
    st = conn.createStatement();
    ResultSet rs = st.executeQuery("SELECT * FROM survey");

    rs = st.executeQuery("SELECT COUNT(*) FROM survey");
    // get the number of rows from the result set
    rs.next();
    int rowCount = rs.getInt(1);
    System.out.println(rowCount);

    rs.close();
    st.close();
    conn.close();

  }

  private static Connection getConnection() throws Exception {
    Class.forName("org.hsqldb.jdbcDriver");
    String url = "jdbc:hsqldb:mem:data/tutorial";

    return DriverManager.getConnection(url, "sa", "");
  }
}

ResultSet имеет свои методы, которые перемещают курсор вперед и назад в зависимости от предоставленной опции. По умолчанию, это движение вперед(с параметрами type_forward_only результирующего типа). Если константы, указывающие на Прокручиваемость и обновление результирующего набора правильно, вы можете в конечном итоге получить ошибку. Например, перед стартом() Этот метод не действует, если результирующий набор не содержит строк. Выдает ошибку, если это не TYPE_FORWARD_ONLY.

лучший способ проверить, если пустые строки были извлечены - - - просто вставить новая запись после проверки несуществования

if( rs.next() ){

   Do nothing
} else {
  No records fetched!
}

посмотреть здесь

вот некоторый код, который позволяет избежать получения count для создания экземпляра массива, но вместо этого использует ArrayList и непосредственно перед возвращением преобразует ArrayList в необходимый тип массива.

обратите внимание, что классный руководитель тут ISupervisor реализует интерфейс, но в Java вы не можете разыграть от Object[] (что ArrayList-это простой метод toArray() возвращает) в ISupervisor[] (как я думаю, вы это сможете сделать в C#), так что вам придется перебрать все элементы списка и заполните результат матрица.

/**
 * Get Supervisors for given program id
 * @param connection
 * @param programId
 * @return ISupervisor[]
 * @throws SQLException
 */
public static ISupervisor[] getSupervisors(Connection connection, String programId)
  throws SQLException
{
  ArrayList supervisors = new ArrayList();

  PreparedStatement statement = connection.prepareStatement(SQL.GET_SUPERVISORS);
  try {
    statement.setString(SQL.GET_SUPERVISORS_PARAM_PROGRAMID, programId);
    ResultSet resultSet = statement.executeQuery();  

    if (resultSet != null) {
      while (resultSet.next()) {
        Supervisor s = new Supervisor();
        s.setId(resultSet.getInt(SQL.GET_SUPERVISORS_RESULT_ID));
        s.setFirstName(resultSet.getString(SQL.GET_SUPERVISORS_RESULT_FIRSTNAME));
        s.setLastName(resultSet.getString(SQL.GET_SUPERVISORS_RESULT_LASTNAME));
        s.setAssignmentCount(resultSet.getInt(SQL.GET_SUPERVISORS_RESULT_ASSIGNMENT_COUNT));
        s.setAssignment2Count(resultSet.getInt(SQL.GET_SUPERVISORS_RESULT_ASSIGNMENT2_COUNT));
        supervisors.add(s);
      }
      resultSet.close();
    }
  } finally {
    statement.close();
  }

  int count = supervisors.size();
  ISupervisor[] result = new ISupervisor[count];
  for (int i=0; i<count; i++)
    result[i] = (ISupervisor)supervisors.get(i);
  return result;
}

следующие два варианта работали для меня:

1) функция, которая возвращает количество строк в результирующем наборе.

private int resultSetCount(ResultSet resultSet) throws SQLException{
    try{
        int i = 0;
        while (resultSet.next()) {
            i++;
        }
        return i;
    } catch (Exception e){
       System.out.println("Error getting row count");
       e.printStackTrace();
    }
    return 0;
}

2) Создайте второй оператор SQL с параметром COUNT.

от http://docs.oracle.com/javase/1.4.2/docs/api/java/sql/ResultSetMetaData.html

 ResultSet rs = stmt.executeQuery("SELECT a, b, c FROM TABLE2");
 ResultSetMetaData rsmd = rs.getMetaData();
 int numberOfColumns = rsmd.getColumnCount();

результирующий набор содержит метаданные, которые дают количество строк.