繁体   English   中英

大阵列 DML (FireDAC) 工作因 PostgreSQL 而失败

[英]Big Array DML (FireDAC) work failded with PostgreSQL

我需要向我的 PostgreSQL(v9.5) 表中插入大量行。

这是表格:

create table TaskLog(
  id serial,
  taskid integer,
  x double precision,
  y double precision,
  loc character varying(50),
  speed smallint,
  gpstime timestamp without time zone,
  veh character varying(16),
  vin character(17),
  regdate date,
  enabled boolean,
  remake character varying(100),
  isdel boolean,
  alarm integer,
  CONSTRAINT pk_delphi_id PRIMARY KEY (id)
 )

我使用 FireDAC(Delphi XE10.1) 插入行:

function RandomStr(aLength : Integer) : string;
var
  X: Integer;
begin
  if aLength <= 0 then exit;
  SetLength(Result, aLength);
  for X:=1 to aLength do
    Result[X] := Chr(Random(26) + 65);
end;

procedure TForm7.Button6Click(Sender: TObject);
var
  i: Integer;
  Watch: TStopwatch;
begin
  Watch := TStopwatch.StartNew;
  try
    FDQuery1.SQL.Text :=
      'insert into TaskLog values(default, :f1, :f2, :f3, :f4, :f5, :f6, ' +
      ':f7, :f8, :f9, :f10, :f11, :f12, :f13)';
    FDQuery1.Params.ArraySize := StrToInt(Edit1.text);  //<--- Change the ArraySize

    for i := 0 to FDQuery1.Params.ArraySize - 1 do
    begin
      FDQuery1.Params[0].AsIntegers[i] := Random(9999999);
      FDQuery1.Params[1].AsFloats[i] := Random(114) + Random;
      FDQuery1.Params[2].AsFloats[i] := Random(90) + Random;
      FDQuery1.Params[3].AsStrings[i] := RandomStr(Random(50));
      FDQuery1.Params[4].AsSmallInts[i] := Random(1990);
      FDQuery1.Params[5].AsDateTimes[i] := IncSecond(IncDay(Now, -(Random(100) + 1)), Random(99999));
      FDQuery1.Params[6].AsStrings[i] := RandomStr(Random(16));
      FDQuery1.Params[7].AsStrings[i] := RandomStr(Random(17));
      FDQuery1.Params[8].AsDates[i] := IncDay(Now, -(Random(365) + 1));
      FDQuery1.Params[9].AsBooleans[i] := Odd(Random(200));
      FDQuery1.Params[10].AsStrings[i] := RandomStr(Random(100));
      FDQuery1.Params[11].AsBooleans[i] := Odd(Random(100));
      FDQuery1.Params[12].AsIntegers[i] := Random(100000);
    end;
    FDQuery1.Execute(FDQuery1.Params.ArraySize);
    Watch.Stop;

    Memo1.Lines.Add('Should be inserted ' + IntToStr(FDQuery1.Params.ArraySize) + ' lines');
    Memo1.Lines.Add('Actually inserted ' + IntToStr(FDQuery1.RowsAffected) + ' lines');
    Memo1.Lines.Add('Take ' + Watch.ElapsedMilliseconds.ToString + ' seconds');
  except
    Memo1.Lines.Add(Exception(ExceptObject).Message);
  end;
end;

当我设置 FDQuery1.Params.ArraySize:=1000 时它工作正常,当我设置 FDQuery1.Params.ArraySize:=10000 时它工作失败,无法插入记录。

ArraySize 属性是否对 PostgreSQL 有大小限制?

const batch_part = 2000;
****    
PostgreSQL.Query.Params.ArraySize := Total;
****
// отправка пакетами в цикле / sending packets in a loop
if Total > batch_part then begin
    j:= Total div batch_part;
    for n := 1 to j do begin
      PostgreSQL.Query.Execute(n*batch_part, (n-1)*batch_part);  // #Batch INSERT operation
      LogFile.Write(Format('FDPostgreSQL.Query.Execute(%d,%d)', [n*batch_part, (n-1)*batch_part]));
    end;
    if (Total mod batch_part) > 0 then begin // остаток / remnant
      PostgreSQL.Query.Execute((Total mod batch_part)+(n-1)*batch_part, (n-1)*batch_part);  // #Batch INSERT operation
      LogFile.Write(Format('FDPostgreSQL.Query.Execute(%d,%d)', [(Total mod batch_part)+(n-1)*batch_part, (n-1)*batch_part]));
    end;
end
else begin
    PostgreSQL.Query.Execute(Total, 0);
    LogFile.Write(Format('FDPostgreSQL.Query.Execute(%d,0)', [Total]));
end;

LogFile:
[04.08.2022 10:23:21.678] Batch INSERT in FDPostgreSQL...
[04.08.2022 10:23:22.079] FDPostgreSQL Execute(2000,0)
[04.08.2022 10:23:22.154] FDPostgreSQL Execute(4000,2000)
[04.08.2022 10:23:22.227] FDPostgreSQL Execute(6000,4000)
[04.08.2022 10:23:22.299] FDPostgreSQL Execute(8000,6000)
[04.08.2022 10:23:22.373] FDPostgreSQL Execute(10000,8000)
[04.08.2022 10:23:22.443] FDPostgreSQL Execute(12000,10000)
[04.08.2022 10:23:22.516] FDPostgreSQL Execute(13014,12000)
[04.08.2022 10:23:22.540] Batch INSERT finished: 13014 records.

服务器端 SQL: INSERT INTO proposal_sid VALUES(DEFAULT, $1, $2, $3, $4, $5, $6, $7, $8),(DEFAULT, $9, $10, $11, $12, $13, $14, $15, $16),(DEFAULT , $17, $18, $19, $20, $21, $22, $23, $24)... -- 1999 次

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM