Как подсчитать количество строк, возвращаемых в моем читателе SQLite в C #? - PullRequest
11 голосов
/ 07 июня 2009

Я работаю в Microsoft Visual C # 2008 Express и с SQLite.

Я запрашиваю свою базу данных примерно так:

SQLiteCommand cmd = new SQLiteCommand(conn);

cmd.CommandText = "select id from myTable where word = '" + word + "';";
cmd.CommandType = CommandType.Text;
SQLiteDataReader reader = cmd.ExecuteReader();

Тогда я делаю что-то вроде этого:

if (reader.HasRows == true) {
    while (reader.Read()) {
        // I do stuff here
    }
}

То, что я хочу сделать, - это подсчитать количество строк до . Я делаю "reader.Read ()", поскольку возвращаемое число повлияет на то, что я хочу / нужно сделать. Я знаю, что могу добавить счетчик в операторе while, но мне действительно нужно знать его раньше.

Есть предложения?

Ответы [ 11 ]

26 голосов
/ 07 июня 2009

DataReader работает лениво, поэтому он не собирает весь набор строк перед началом. Это оставляет вам два варианта:

  1. Итерация и подсчет
  2. Количество в операторе SQL.

Поскольку я больше разбираюсь в SQL, я подсчитаю в выражении SQL:

cmd.CommandText = "select count(id) from myTable where word = '" + word + "';";
cmd.CommandType = CommandType.Text;
int RowCount = 0;

RowCount = Convert.ToInt32(cmd.ExecuteScalar());

cmd.CommandText = "select id from myTable where word = '" + word + "';";
SQLiteDataReader reader = cmd.ExecuteReader();

//...

Обратите внимание, как я считал *, а не id в начале. Это потому, что count (id) будет игнорировать идентификаторы, в то время как count (*) будет игнорировать только полностью нулевые строки. Если у вас нет нулевых идентификаторов, используйте счетчик (id) (это немного быстрее, в зависимости от размера таблицы).

Обновление: изменено на ExecuteScalar, а также количество (id) на основе комментариев.

2 голосов
/ 07 июня 2009

То, что вы просите, неосуществимо - процитировать Игорь Тандетник , мой акцент:

SQLite создает записи по одной, по запросу, каждый раз, когда вы звоните sqlite3_step. Он просто не знает, сколько их будет , пока на какой-то sqlite3_step назовите это обнаруживает, что больше нет.

(sqlite3_step - это функция в C API SQLite, которую интерфейс C # вызывает здесь для каждой строки в результате).

Вы могли бы сделать сначала "SELECT COUNT(*) from myTable where word = '" + word + "';" перед вашим "реальным" запросом - , который сообщит вам, сколько строк вы собираетесь получить из реального запроса.

2 голосов
/ 07 июня 2009

Сделайте второй запрос:

cmd.CommandText = "select count(id) from myTable where word = '" + word + "';";
cmd.CommandType = CommandType.Text;
SQLiteDataReader reader = cmd.ExecuteReader();

Ваш читатель будет содержать одну строку с одним столбцом, содержащим количество строк в наборе результатов. Подсчет будет выполнен на сервере, поэтому он должен быть очень быстрым.

1 голос
/ 07 июня 2009

Обычно я бы сделал

select count(1) from myTable where word = '" + word + "';";

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

Принимая во внимание это, count (1) будет содержать пустые строки. Но я готов поправиться, если я ошибаюсь.

1 голос
/ 07 июня 2009

Если вы загружаете только столбец id из базы данных, не будет ли проще просто загрузить в List<string> и затем работать в памяти?

0 голосов
/ 26 февраля 2019

Вот моя полная реализация в статическом методе. Вы сможете подключить это к своему классу (замените _STR_DB_FILENAME & STR_TABLE_NAME на имя файла базы данных и имя таблицы).

    /// <summary>
    /// Returns a count of the number of items in the database.
    /// </summary>
    /// <returns></returns>
    public static int GetNumberOfItemsInDB()
    {
        // Initialize the count variable to be returned
        int count = 0;            

        // Start connection to db
        using (SqliteConnection db =
            new SqliteConnection("Filename=" + _STR_DB_FILENAME))
        {
            // open connection
            db.Open();

            SqliteCommand queryCommand = new SqliteCommand();
            queryCommand.Connection = db;

            // Use parameterized query to prevent SQL injection attacks
            queryCommand.CommandText = "SELECT COUNT(*) FROM " + _STR_TABLE_NAME;
            // Execute command and convert response to Int
            count = Convert.ToInt32(queryCommand.ExecuteScalar());
            // Close connection
            db.Close();
        }
        // return result(count)
        return count;
    }

Примечание. Чтобы повысить производительность, вы можете заменить «» в «SELECT COUNT ()….» с именем столбца первичного ключа в вашей таблице для более быстрой производительности на больших наборах данных.

0 голосов
/ 24 февраля 2017

Конечно, лучший способ получить количество строк будет выглядеть примерно так: -

 SQLiteDataReader reader = SendReturnSQLCommand(dbConnection, "SELECT COUNT(*) AS rec_count FROM table WHERE field = 'some_value';");
      if (reader.HasRows) {
         reader.Read();
        int  count = Convert.ToInt32(reader["rec_count"].ToString());

...

    }

Таким образом, вам не нужно перебирать строки

0 голосов
/ 01 февраля 2017
SQLiteCommand cmd = new SQLiteCommand(conn);
cmd.CommandText = "select id from myTable where word = '" + word + "';";
SQLiteDataReader reader = cmd.ExecuteReader();

while (reader.Read())
       {
          total_rows_in_resultset++;
       }
0 голосов
/ 21 мая 2014

Попробуйте это,

SQLiteCommand cmd = new SQLiteCommand(conn);

cmd.CommandText = "select id from myTable where word = '" + word + "';";

SQLiteDataReader reader = cmd.ExecuteReader();

while (reader.HasRows)

     reader.Read();

int total_rows_in_resultset = reader.StepCount;

total_rows_in_resultset дает количество строк в наборе результатов после обработки запроса

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

0 голосов
/ 08 июня 2009

Вы должны считать с select count... from...

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

См. Здесь: Как мне обойти проблему "" "в sqlite и c #?

(Таким образом, помимо скоростных параметризованных запросов, есть и 2 других преимущества.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...