Подтвердить что ты не робот

Как получить счетчик строк, используя ResultSet в Java?

Я пытаюсь создать простой метод, который получает ResultSet как параметр и возвращает int, который содержит количество строк 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.

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

4b9b3361

Ответ 1

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

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

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

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

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

Ответ 2

ваш код создания кода 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;

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

Ответ 3

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();

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

Спасибо..

Ответ 4

Сделайте запрос SELECT COUNT(*) FROM ....

Ответ 5

Я только что сделал метод 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;
}

Ответ 6

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

Пример кода, чтобы получить общее количество строк 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", "");
  }
}

Ответ 7

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

Ответ 8

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

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

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

Ответ 9

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

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

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

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

Ответ 10

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

Лучший способ проверить, были ли загружены пустые строки. Просто вставить новую запись после проверки отсутствия.

if( rs.next() ){

   Do nothing
} else {
  No records fetched!
}

Смотрите здесь

Ответ 11

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

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

/**
 * 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;
}

Ответ 12

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

1) Функция, возвращающая количество строк в ResultSet.

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.