Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Базы данных и репортинг > Лечим прокрутку для ADODataSet с clUseServer


Автор: Чучмек 10.3.2013, 12:47
Если использовать серверный курсор, прокрутка имеет всего три позиции - начало,конец, и посредине( сдвиг на страницу).
Пришлось разобраться с серверным курсором.
Это замена, для постраничной, выборки от мелкософта. 
Отсутствие LIMIT, было для меня большим разочарованием в MS SQL
Разбираясь с прокруткой нашел следующие
DBGrids
Код

procedure TCustomDBGrid.UpdateScrollBar;
var
  SIOld, SINew: TScrollInfo;
begin
...
    with FDatalink.DataSet do
    begin
...
      if IsSequenced then
      begin
        SINew.nMin := 1;
        SINew.nPage := Self.VisibleRowCount;
        SINew.nMax := Integer(DWORD(RecordCount) + SINew.nPage - 1);
        if State in [dsInactive, dsBrowse, dsEdit] then
          SINew.nPos := RecNo;  // else keep old pos
      end
      else
      begin
        SINew.nMin := 0;
        SINew.nPage := 0;
        SINew.nMax := 4;
        if FDataLink.BOF then SINew.nPos := 0
        else if FDataLink.EOF then SINew.nPos := 4
        else SINew.nPos := 2;
      end;
...
end;

и
ADODB
Код

function TCustomADODataSet.IsSequenced: Boolean;
begin
  Result := Assigned(RecordSet) and Recordset.Supports(adApproxPosition) and
    (CursorLocation <> clUseServer) and not Filtered;
end;

Переопределяем IsSequenced
Код

function TMyAdoTable.IsSequenced: Boolean;
begin
if (CursorLocation=clUseServer) and (CursorType=ctKeyset)then result:=true else
 result:= inherited IsSequenced;
end;

Запускаем. Тревожное ожидание. Подозрительная задержка. Но вот появляется...
О чудо!!! Нормальная прокрутка!!!  
Смотрим сколько данных было получено...
Восторг пропадает. Грузилось так, как если бы вся таблица целиком.   
Ищем причину. smile  smile  smile  smile smile  
Причина кроется в вызове метода Get_RecordCount интерфейса Recordset15. smile smile  smile 
Легко проверить посмотрев сколько времени выполняется вызов  GetRecordCount ( и сколько при этом подгружается данных).
Возможно в другой версии Microsoft ActiveX Data Objects Library эта проблема устранена.
Поскольку определить число строк в курсоре, при работе с курсором  средствами TSQL, очень просто (переменная @@CURSOR_ROWS после открытия курсора).
Я пойду на хитрость. Переопределю GetRecordCount.
Код

function TMyAdoTable.GetRecordCount: Integer;
var
 n:olevariant;
begin
if (CursorLocation=clUseServer) and (CursorType=ctKeyset)then
 begin
 n:=Recordset.AbsolutePosition;
 Recordset.MoveLast;
 result:=Recordset.AbsolutePosition;
 Recordset.AbsolutePosition:=n ;
 end
 else result:=inherited GetRecordCount;
end;



Код

TMyAdoTable=class(TADOTable)
 protected
  function IsSequenced: Boolean; override;
  function GetRecordCount: Integer; override;
 end;


 smile  smile  smile  smile  smile  smile  smile  smile  smile 


Автор: Illusion Dolphin 10.3.2013, 13:00
Цитата

Отсутствие LIMIT, было для меня большим разочарованием в MS SQL

В MS SQL есть TOP, ROW_NUMBER ( ) и другие примочки

Автор: Чучмек 10.3.2013, 13:06
TOP это TOP - первые n записей.
Все остальное, кроме курсора - костыли.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)