【问题标题】:SQLite query results limitationSQLite 查询结果限制
【发布时间】:2020-11-29 00:34:32
【问题描述】:

我正在尝试从SQLite 数据库表中获取数据,但我无法获取超过 50 行。有 50 行的限制吗? 我的代码如下所示:

unit Unit1;

interface

uses
FireDAC.Stan.Def, FireDAC.DApt, FireDAC.Phys.SQLite, FireDAC.VCLUI.Wait, FireDAC.Comp.Client, FireDAC.Stan.Async;

type
  TRaportas = record
    Pradzia: TDateTime;
    Pabaiga: TDateTime;
    Trukme: Integer;
    idPriezastis: Integer;
    Priezastis: string;
    idVieta: Integer;
    Vieta: string;
    Komentaras: string;
  end;

procedure TForm1.btnRaportasClick(Sender: TObject);
var
sqlConn: TFDConnection;
query: TFDQuery;
prastovuRec: array of TRaportas;
i: Integer;
begin
  dbVieta := edt2.Text;
  sqlConn := TFDConnection.Create(nil);
  //sqlConn.Connected := False;
  sqlConn.DriverName := 'SQLITE';
  sqlConn.Params.Values['DataBase'] := dbVieta;  
  query := TFDQuery.Create(nil);
  query.Connection := sqlConn;
  query.SQL.Text := 'SELECT * FROM Prastovos WHERE ID >= :_ID';
  query.ParamByName('_ID').Value := StrToIntDef(edt3.Text, 656);
  sqlConn.Open();
  query.Open();
  SetLength(prastovuRec, query.RowsAffected);
  edt4.Text := IntToStr(query.RowsAffected);
  for i := 0 to query.RowsAffected - 1 do
    begin
      with mRaportas do
        begin
          Pradzia := query.FieldByName('Pradzia').AsDateTime;
          Pabaiga := query.FieldByName('Pabaiga').AsDateTime;
          Trukme := query.FieldByName('Trukme').AsInteger;
          idPriezastis := query.FieldByName('IDpriezastis').AsInteger;
          Priezastis := query.FieldByName('Priezastis').AsString;
          idVieta := query.FieldByName('IDvieta').AsInteger;
          Vieta := query.FieldByName('Vieta').AsString;
          Komentaras := query.FieldByName('Komentaras').AsString;
        end;
      prastovuRec[i] := mRaportas;
      query.Next;
    end;
  query.Close;
  query.DisposeOf;
  sqlConn.Close;
  sqlConn.Free;
end;

【问题讨论】:

    标签: sqlite delphi delphi-10.2-tokyo


    【解决方案1】:

    您的代码中有很多错误和误解。为简化起见,我将修复您的代码以使其正常工作。自己研究差异。

    unit Unit1;
    
    interface
    
    uses
      FireDAC.Stan.Def, FireDAC.DApt, FireDAC.Phys.SQLite, FireDAC.VCLUI.Wait, FireDAC.Comp.Client, 
      FireDAC.Stan.Async, FireDAC.Stan.Option;
    
    type
      TRaportas = record
        Pradzia: TDateTime;
        Pabaiga: TDateTime;
        Trukme: Integer;
        idPriezastis: Integer;
        Priezastis: string;
        idVieta: Integer;
        Vieta: string;
        Komentaras: string;
      end;
    
    var
      prastovuRec: array of TRaportas;
    
    procedure TForm1.Button7Click(Sender: TObject);
    var
      sqlConn: TFDConnection;
      query: TFDQuery;
      mRaportas: TRaportas;
      i: Integer;
    begin
      sqlConn := TFDConnection.Create(nil);
      query := TFDQuery.Create(nil);
      try
        sqlConn.DriverName := 'SQLITE';
        sqlConn.Params.Values['DataBase'] := edt2.Text;
    
        query.Connection := sqlConn;
        query.FetchOptions.Mode := fmAll;   // essential if you want to use RecordCount
        query.SQL.Text := 'SELECT * FROM Prastovos WHERE ID >= :_ID';
        query.ParamByName('_ID').Value := StrToIntDef(edt3.Text, 656);
        query.Open();
    
        edt4.Text := IntToStr(query.RecordCount);
        SetLength(prastovuRec, query.RecordCount);
        i := 0;
    
        while not query.Eof do
        begin
          mRaportas := Default(TRaportas);  // not necessary if you assign all record fields
          mRaportas.Pradzia := query.FieldByName('Pradzia').AsDateTime;
          mRaportas.Pabaiga := query.FieldByName('Pabaiga').AsDateTime;
          mRaportas.Trukme := query.FieldByName('Trukme').AsInteger;
          mRaportas.idPriezastis := query.FieldByName('IDpriezastis').AsInteger;
          mRaportas.Priezastis := query.FieldByName('Priezastis').AsString;
          mRaportas.idVieta := query.FieldByName('IDvieta').AsInteger;
          mRaportas.Vieta := query.FieldByName('Vieta').AsString;
          mRaportas.Komentaras := query.FieldByName('Komentaras').AsString;
          prastovuRec[i] := mRaportas;
          Inc(i);
    
          query.Next;
        end;
        query.Close;
      finally
        query.Free;
        sqlConn.Free;
      end;
    end;
    

    【讨论】:

    • query.FetchOptions.Mode := fmAll; 解决了我的问题。
    • 旁注:将query.FieldByName('....') 置于循环之外有助于提高性能。
    • @ArnaudBouchez 你能说说为什么吗?在循环开始之前,你的意思是在循环之外。
    • @NasreddineGalfout 调用FieldByName() 进行查找,这会降低性能。只需在循环之前执行一次,分配给本地 TField 变量,然后使用它们访问循环内的字段值。更多详情请查看delphitools.info/2010/11/30/… Delphi RTL 从那时起就使用了TDictionary,但是还是有代价的,而且每次调用lowercase(),进行字符串分配和一些转换,所以也有代价.
    • @Arnaud Bouchez 我想知道query.first 是否与循环前第一次调用query.FieldByName('..') 相同?
    【解决方案2】:

    没有,没有特别限制。

    但是您的查询中有一个 WHERE 子句。这可能会限制结果集。检查您使用的值。

    【讨论】:

    • 奇怪,但 query.RowsAffected 返回最大值 50。如果我将其更改为 while not query.Eof do,那么我会得到所有记录。
    猜你喜欢
    • 2011-09-28
    • 1970-01-01
    • 1970-01-01
    • 2014-08-04
    • 2016-04-01
    • 2011-01-17
    • 2020-10-07
    • 2013-06-22
    • 2020-05-07
    相关资源
    最近更新 更多