SDAC -RecordCount и FetchAll - PullRequest
       19

SDAC -RecordCount и FetchAll

2 голосов
/ 09 июня 2011

Я использую SDAC компоненты для запроса базы данных SQL Server 2008. Он имеет свойство recordcount, как и все наборы данных, а также свойство FetchAll (которое, я думаю, называется packedrecords на clientdatasets). Сказал, что у меня есть несколько вопросов:

1 - Если я установлю FetchAll = True, свойство recordcount вернет ok. Но в этом случае, когда у меня большая база данных и мой запрос возвращает много строк, иногда объем памяти сильно увеличивается (потому что он выбирает все данные, чтобы получить recordcount, конечно).

2 - Если я установлю FetchAll = False, recordcount вернет -1, и память не увеличится. Но мне действительно нужен счет записи. И я также хочу создать для этого универсальную функцию, поэтому мне не нужно менять все мои существующие запросы.

Что можно сделать, чтобы recordcount работал и в этом случае использовалось мало памяти приложения?

Пожалуйста, не пишите, что мне не нужен учет записей (или что я должен использовать EOF и BOF), потому что я действительно это делаю, и это не вопрос.

Я думал об использовании запроса для определения количества записей, но у него есть некоторые проблемы, поскольку мой запрос будет выполнен дважды (1 для количества записей, 1 для данных)

EDIT

@ Йохан указал на хорошее решение, и, похоже, оно работает. Кто-нибудь может это подтвердить? Я использую 1 TMSCconnection для каждого TMSQuery (потому что я использую потоки), поэтому я не думаю, что это будет проблемой, не так ли?

  MSQuery1.FetchAll := False;
  MSQuery1.FetchRows := 10;
  MSQuery1.SQL.Text := 'select * from cidade';
  MSQuery1.Open;
  ShowMessage(IntToStr(MSQuery1.RecordCount)); //returns 10
  MSQuery1.Close;

  MSQuery2.SQL.Text := 'SELECT @@rowcount AS num_of_rows';
  MSQuery2.Open;
  ShowMessage(MSQuery2.FieldByName('num_of_rows').AsString); //returns 289

РЕДАКТИРОВАТЬ 2 *

MSQuery1 должен быть закрыт, иначе MSQuery2 не вернет num_of_rows. Почему это так?

  MSQuery1.FetchAll := False;
  MSQuery1.FetchRows := 10;
  MSQuery1.SQL.Text := 'select * from cidade';
  MSQuery1.Open;
  ShowMessage(IntToStr(MSQuery1.RecordCount)); //returns 10
  //MSQuery1.Close; <<commented

  MSQuery2.SQL.Text := 'SELECT @@rowcount AS num_of_rows';
  MSQuery2.Open;
  ShowMessage(MSQuery2.FieldByName('num_of_rows').AsString); //returns 0

Ответы [ 2 ]

2 голосов
/ 09 июня 2011

Запустите ваш запрос как обычно, чем закрыть запрос

MSQuery1.SQL.Text := 'select * from cidade';     
MSQuery1.Open;     
MSQuery1.Close;  

Вам нужен close, иначе SQL-сервер еще не закрыл курсор и не зарегистрирует запрос как «завершенный».

и сразу же выполните следующий запрос:

SELECT @@rowcount AS num_of_rows

Это выберет общее количество строк, которые вы прочитали в последний раз select.
Он также выберет количество строк, на которые повлиял ваш оператор update / delete / insert.

См .: http://technet.microsoft.com/en-us/library/ms187316.aspx

Обратите внимание, что эта переменная для соединения , поэтому запросы в других соединениях не влияют на вас.

2 голосов
/ 09 июня 2011

Я использую ODAC и считаю, что SDAC наследуется от тех же базовых классов и работает так же, как ODAC.В ODAC есть опция QueryRecCount в разделе Параметры в компоненте запроса.Ищите TCustomDADataSet.Options.QueryRecCount в файле справки.

Установка QueryRecCount = True и FetchAll = False уменьшит использование памяти и даст вам счетчик записей.Но SDAC будет выполнять второй запрос в фоновом режиме, чтобы получить количество записей, поэтому он добавляет немного дополнительного времени к вашему запросу.

Посмотрите на запись на форуме Devart по адресу http://www.devart.com/forums/viewtopic.php?t=8143.

...