Проблема с памятью при использовании dbExpress - PullRequest
0 голосов
/ 21 июня 2019

Я должен поработать над устаревшим приложением Delphi 7 и хотел переключиться с ADO компонентов на dbExpress, но это доставляет мне странную проблему.

Настройка проста
, когдаЯ использую ADO У меня есть это

ADOConnection
ADOQuery

DataSetProvider
ClientDataSet
DataSource
DBGrid

при выполнении запроса, который возвращает около 50000 строк, проблем нет.
Я могу прокрутить до последней строки, проблем не возникает

Теперь, когда я использую dbExpress У меня есть следующая настройка.
Обратите внимание, что я переключил только первые 2 компонента, все остальные остаются неизменными.

SQLConnection
SQLQuery

DataSetProvider
ClientDataSet
DataSource
DBGrid

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

Недостаточно памяти для этой операции

Вв обоих случаях я использую один и тот же код

ClientDataSet1.Open;

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

Как это возможно, что ClientDataSet может удерживать все 50000 строк при использовании ADO, но не при использовании dbExpress?
Как я могу обойти это?

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

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, DB, DBClient, Provider, ADODB, StdCtrls, DBCtrls, Grids,
  DBGrids, ExtCtrls, DBXpress, FMTBcd, SqlExpr;

type
  TForm1 = class(TForm)
    Panel1: TPanel;
    DBGrid1: TDBGrid;
    DBNavigator1: TDBNavigator;
    Button1: TButton;
    Button2: TButton;
    DataSetProvider1: TDataSetProvider;
    ClientDataSet1: TClientDataSet;
    DataSource1: TDataSource;
    Label1: TLabel;
    SQLConnection1: TSQLConnection;
    SQLQuery1: TSQLQuery;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
  public
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  ClientDataSet1.Open;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  ClientDataSet1.Close;
end;

end.

И DFM (я оставил постоянные полячтобы он был немного меньше)

object Form1: TForm1
  Left = 347
  Top = 125
  Width = 1305
  Height = 675
  Caption = 'Form1'
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  OldCreateOrder = False
  PixelsPerInch = 96
  TextHeight = 13
  object Panel1: TPanel
    Left = 0
    Top = 0
    Width = 1289
    Height = 97
    Align = alTop
    Caption = 'Panel1'
    TabOrder = 0
    object Label1: TLabel
      Left = 240
      Top = 32
      Width = 32
      Height = 13
      Caption = 'Label1'
    end
    object DBNavigator1: TDBNavigator
      Left = 16
      Top = 64
      Width = 240
      Height = 25
      DataSource = DataSource1
      TabOrder = 0
    end
    object Button1: TButton
      Left = 32
      Top = 24
      Width = 75
      Height = 25
      Caption = 'connect'
      TabOrder = 1
      OnClick = Button1Click
    end
    object Button2: TButton
      Left = 112
      Top = 24
      Width = 75
      Height = 25
      Caption = 'disconnect'
      TabOrder = 2
      OnClick = Button2Click
    end
  end
  object DBGrid1: TDBGrid
    Left = 0
    Top = 97
    Width = 1289
    Height = 539
    Align = alClient
    DataSource = DataSource1
    TabOrder = 1
    TitleFont.Charset = DEFAULT_CHARSET
    TitleFont.Color = clWindowText
    TitleFont.Height = -11
    TitleFont.Name = 'MS Sans Serif'
    TitleFont.Style = []
  end
  object DataSetProvider1: TDataSetProvider
    DataSet = SQLQuery1
    Left = 512
    Top = 328
  end
  object ClientDataSet1: TClientDataSet
    Aggregates = <>
    PacketRecords = 50
    Params = <>
    ProviderName = 'DataSetProvider1'
    Left = 512
    Top = 392
  end
  object DataSource1: TDataSource
    DataSet = ClientDataSet1
    Left = 528
    Top = 456
  end
  object SQLConnection1: TSQLConnection
    ConnectionName = 'MSSQLConnection'
    DriverName = 'MSSQL'
    GetDriverFunc = 'getSQLDriverMSSQL'
    LibraryName = 'dbexpmss.dll'
    LoginPrompt = False
    Params.Strings = (
      'DriverName=MSSQL'
      'HostName=XXXXXX'
      'DataBase=GTT_Test'
      'User_Name=XXX'
      'Password=XXX'
      'BlobSize=-1'
      'ErrorResourceFile='
      'LocaleCode=0000'
      'MSSQL TransIsolation=ReadCommited'
      'OS Authentication=False')
    VendorLib = 'oledb'
    Left = 584
    Top = 208
  end
  object SQLQuery1: TSQLQuery
    MaxBlobSize = -1
    Params = <>
    SQL.Strings = (
      'select * from vwRitComplete')
    SQLConnection = SQLConnection1
    Left = 584
    Top = 272
  end
end
...