Link to home
Start Free TrialLog in
Avatar of powerlog
powerlogFlag for Brazil

asked on

AutoUpdate - ExecSql Freeze

Hello,

My application freeze at ExecSql function. Script have 17.000 lines.

First step:
  mmAtu.clear;
  for I := gRhParameOri.versbd+1 to gVersaoBDAtual do
  begin
    mmLer.Clear;
    xArq := gPathAtuVer+'ver'+inttostr(I)+'.txt';
    if FileExists(xArq) then
      mmLer.Lines.LoadFromFile(xArq);
    mmAtu.text := mmAtu.text + mmLer.text;
  end;

Open in new window


And after:

  dmParam.qyAtuVer.Close;
  dmParam.qyAtuVer.SQL.Clear;
  dmParam.qyAtuVer.Sql.Text := mmAtu.text;
  dmParam.qyAtuVer.ExecSQL;

Open in new window


I'll need separate in more files ? Is there any way to check the progress of execution ?

Thanks
Avatar of Thommy
Thommy
Flag of Germany image

Try using TSQLMonitor to monitor sql communication with your database server...
ASKER CERTIFIED SOLUTION
Avatar of Geert G
Geert G
Flag of Belgium image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
>>Script have 17.000 lines.

most database like sql server, oracle, interbase .... etc
have something like stored procedures

with such a long script, you'll need items contained in transactions to have consistent data
why are loading the query text twice ?
and why are u using a memo as in between >> this is slow !

here is your code, but optimized a little

var List: TStringList;

begin
  List := TStringList.Create;
  try
    dmParam.qyAtuVer.Close;
    dmParam.qyAtuVer.SQL.Clear;
    dmParam.qyAtuVer.SQL.BeginUpdate;
    try
      for I := gRhParameOri.versbd+1 to gVersaoBDAtual do
      begin
        xArq := gPathAtuVer+'ver'+inttostr(I)+'.txt';
        if FileExists(xArq) then
        begin
          List.LoadFromFile(xArq);
          dmParam.qyAtuVer.SQL.AddLines(List);
        end;
      end;
    finally
      dmParam.qyAtuVer.SQL.EndUpdate;
    end;
  finally
    List.Free;
  end;
  dmParam.qyAtuVer.ExecSQL;

Open in new window


lol >>> divide the script >>> why execute the separate pieces and indicate progress ?
you could even count the total steps with a procedure like filecount
and show the progress with showprogress

var List: TStringList;
  step, totalsteps: integer;
  error: string;
begin
  step := 1;
  dmParam.qyAtuVer.Close;
  try
    TotalSteps := FileCount(gPathAtuVer, 'ver*.txt');
    for I := gRhParameOri.versbd+1 to gVersaoBDAtual do
    begin
      xArq := gPathAtuVer+'ver'+inttostr(I)+'.txt';
      if FileExists(xArq) then
      try
        dmParam.qyAtuVer.SQL.LoadFromFile(xArq);
        dmParam.qyAtuVer.ExecSQL;
        Step := Step + 1;
        ShowProgress(Step, TotalSteps, '');
      except
        on E: exception do 
          Raise Exception.Create('Failed at step ' + IntToStr(Step) + #13#10 + 
            'Error message: ' + E.Message);
      end;
    end;
  except
    on E: Exception do 
    begin
      ShowProgress(Step, TotalSteps, E.Message);
      Raise;
    end;
  end;

Open in new window


ShowProgress would be something like

procedure TForm1.ShowProgress(Step, Total: integer; Msg: string);
begin
  // show the message in a label
  lblProgress.Caption := Msg;
  lblProgress.Update;
  // show the progress in a progressbar
  // pgbProgress.Min := 0;
  // pgbProgress.Max := 100;
  pgbProgress.Position := Round(Step/Total*100);
  pgbProgress.Update;
end;

filecount is a count using the TSearchRec:
(somewhat stolen from systan in this thread:
https://www.experts-exchange.com/questions/27513571/How-to-populate-ListView-control.html)

function FileCount(const AFolder, AFilter: string): integer;
var
  vFindHandle: THandle;
  vFilter    : String;
  vFindData  : WIN32_FIND_DATA;
  AList: TStringList;
begin
  Result := 0;
  AList := TStringlist.Create;
  try
    AList.Clear;
    vFilter := AFolder + '\' + AFilter;
    vFindHandle := FindFirstFile(PChar(vFilter), vFindData);
    if vFindHandle = INVALID_HANDLE_VALUE then
      Exit;

    repeat
      AList.Add(ChangeFileExt(vFindData.cFileName, ''));
    until not FindNextFile(vFindHandle, vFindData);

    Windows.FindClose(vFindHandle);
    if AList.count > 0 then
      Result := AList.Count;
  finally
    AList.Free;
  end;
end;
I would put prograss bar on form and use your first source lines...

...
  ProgressBar1.Max := gVersaoBDAtual;
  ProgressBar1.Min := gRhParameOri.versbd+1;
  ProgressBar1.Position := ProgressBar1.Min;
  dmParam.qyAtuVer.SQLConnection.StartTransaction(..);
  try
    for I := gRhParameOri.versbd+1 to gVersaoBDAtual do
    begin
      xArq := gPathAtuVer+'ver'+inttostr(I)+'.txt';
      if FileExists(xArq) then
      begin
        mmLer.Lines.LoadFromFile(xArq);
        dmParam.qyAtuVer.Sql.Text := mmLer.text;
        dmParam.qyAtuVer.ExecSQL;
      end;
      ProgressBar1.StepIt;
    end;
    dmParam.qyAtuVer.SQLConnection.Commit(...);
  except
    dmParam.qyAtuVer.SQLConnection.Rollback(...);
  end;
...

Open in new window