Looping through records in TUniQuery - Out of memory error
Posted: Sun 24 Mar 2013 23:27
URGENT SUPPORT REQUIRED.
Using: Delphi XE2 Enterprise Update 4.1; UniDAC 4.6.12 Pro; IBM DB2 Express-C 10.1; Delphi VCL forms 32-bit application; running on Windows 8 64-bit; DB2 database is running on Windows Server 2012.
The objective of my routine is to extract the BLOB data from one of the database table fields, and save it to file on disk. It is a large table - between 1 - 10 million rows.
I am using TUniQuery, created in code, without setting any options (thus, default options). I do a SELECT to select all rows, then loop through the rows from beginning to end saving the content of the BLOB field to disk.
When running the code, after some time it gives 'Out of memory' exception.
Please suggest any option to set on the UniQuery to prevent this from happening or suggest a workaround solution. Maybe my logic is wrong and I should not select all rows. I'm not sure. Please help me.
By the way, I have installed IBM Data Server Runtime Client on the same machine as the Delphi app, so the app is connecting to the database without any problems.
Here is my code:
Regards,
Steve Faleiro
Using: Delphi XE2 Enterprise Update 4.1; UniDAC 4.6.12 Pro; IBM DB2 Express-C 10.1; Delphi VCL forms 32-bit application; running on Windows 8 64-bit; DB2 database is running on Windows Server 2012.
The objective of my routine is to extract the BLOB data from one of the database table fields, and save it to file on disk. It is a large table - between 1 - 10 million rows.
I am using TUniQuery, created in code, without setting any options (thus, default options). I do a SELECT to select all rows, then loop through the rows from beginning to end saving the content of the BLOB field to disk.
When running the code, after some time it gives 'Out of memory' exception.
Please suggest any option to set on the UniQuery to prevent this from happening or suggest a workaround solution. Maybe my logic is wrong and I should not select all rows. I'm not sure. Please help me.
By the way, I have installed IBM Data Server Runtime Client on the same machine as the Delphi app, so the app is connecting to the database without any problems.
Here is my code:
Code: Select all
procedure TfMain.btStartClick(Sender: TObject);
var
msg: String;
p, e, n, schm, tbl, fld: String;
uq: TUniQuery;
c, r, pp: Integer;
begin
if not FormValidate(msg) then
begin
ShowMessage(msg);
Exit;
end;
schm := Trim(cmbSchema.Text);
tbl := Trim(lstTable.Items[lstTable.ItemIndex]);
fld := Trim(lstField.Items[lstField.ItemIndex]);
p := deOutPath.Directory;
if not DirectoryExists(p) then
ForceDirectories(p);
e := edtFileExt.Text;
uq := TUniQuery.Create(nil);
try
uq.Connection := UniConnection1;
uq.SQL.Text := 'SELECT COUNT(1) C FROM ' + schm + '.' + tbl;
uq.Open;
r := uq.FieldByName('C').AsInteger;
uq.Close;
uq.SQL.Text := 'SELECT ' + fld + ' FROM ' + schm + '.' + tbl;
uq.Open;
c := 1;
while not uq.Eof do
begin
n := p + '\FILE' + Format('%.7d', [c]) + e;
uq.GetBlob(fld).SaveToFile(n);
pp := Trunc(c / r * 100);
pbProg.Position := pp;
lbProg.Caption := Format('%d%% (%d of %d records processed)', [pp, c, r]);
Application.ProcessMessages;
Inc(c);
uq.Next;
end;
uq.Close;
ShowMessage('Done!');
finally
uq.Free;
end;
end;
Regards,
Steve Faleiro