Активация/Деактивация Fetch

Обсуждение возникших проблем, предложений и ошибок SDAC компонентов
Ответить
krants
Сообщения: 3
Зарегистрирован: Вт 11 фев 2014 11:18

Активация/Деактивация Fetch

Сообщение krants » Вт 11 фев 2014 12:03

Добрый день!
При использовании FetchAll := False
имеется необходимость пересчитывать и выводить "итоги" только по полученным записям.
т.к. при переборе записей принудительно вызывается Fetch, подсчет будет проходить до тех пор пока не догрузятся все записи, что "противоречит" заданной опции. :(

на данный момент в TMSQuery имеется возможность только отключить Fetch:
OnMSQueryBeforeFetch(DataSet: TCustomDADataSet; var Cancel: Boolean);
но активировать обратно, - нету.

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

Просто для примера, как необходимое использование методов "перекрытия" Fetch:

Код: Выделить всё

procedure ReCalcSummary;
var
  key: integer;
begin
  sqlQuery.DisableControls;
  try
    sqlQuery.DisableFetch; //Временно отключаем
    try
      key := sqlQueryID.AsInteger;
      while not sqlQuery.Eof do
      begin
        //CalcFieldsSummary
        sqlQuery.Next;
      end;
      if key > 0 then
        sqlQuery.Locate('ID', key, []);
    finally
      sqlQuery.EnableFetch; //Возвращаем
    end;
  finally
    sqlQuery.EnableControls;
  end;
end;
Последний раз редактировалось krants Вт 11 фев 2014 14:00, всего редактировалось 1 раз.

Alexp
Devart Team
Сообщения: 349
Зарегистрирован: Пн 27 дек 2010 10:34

Re: Активация/Деактивация Fetch

Сообщение Alexp » Вт 11 фев 2014 12:56

Добрый день,

Для реализации необходимого вам поведения Вы можете использовать цикл от 1 до MSQuery1.FetchRows. В этом цикле вы будете проходить только по зафетченным данным в текущем блоке, например

Код: Выделить всё

var
  i: integer;
begin
  MSQuery1.FetchAll := False;
  MSQuery1.FetchRows := 25;
  MSQuery1.Open; // <-- Получаем первые 25 записей
  while not MSQuery1.Eof do begin
    for i := 1 to MSQuery1.FetchRows  do begin
      //CalcFieldsSummary
      if i <> MSQuery1.FetchRows then // не фетчить следующий блок
        MSQuery1.Next;
    end;
    MSQuery1.Next; // <-- зафетчить следующий блок
  end;
end;

krants
Сообщения: 3
Зарегистрирован: Вт 11 фев 2014 11:18

Re: Активация/Деактивация Fetch

Сообщение krants » Вт 11 фев 2014 14:16

MSQuery1.FetchRows = 25 стоит по умолчанию,
но количество полученных записей может быть больше, в зависимости от первичного заполнения грида или последующего пролистывания записей пользователем.

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

Код: Выделить всё

    for i := 1 to MSQuery1.RecordCount do 
    begin
      //CalcFieldsSummary
      if i < MSQuery1.RecordCount then // не фетчить следующий блок
        MSQuery1.Next;
    end;
но тогда приходится пропускать последнюю запись, что не совсем корректно.

Alexp
Devart Team
Сообщения: 349
Зарегистрирован: Пн 27 дек 2010 10:34

Re: Активация/Деактивация Fetch

Сообщение Alexp » Ср 12 фев 2014 11:36

Для того чтобы не "пропускать" последнюю запись, Вы можете вынести действия CalcFieldsSummary в отдельный метод и вызывать его при условии i = MSQuery1.RecordCount, т.е.

Код: Выделить всё

    for i := 1 to MSQuery1.RecordCount do 
    begin
      CalcFieldsSummary(....); // обработается записи от 1 до MSQuery1.RecordCount - 1
      if i < MSQuery1.RecordCount then // не фетчить следующий блок
        MSQuery1.Next
      else
       CalcFieldsSummary(....); // обработка последней записи
    end;

Ответить