Solved

FireDac batch insertion in Excel or...

  • 12 May 2023
  • 1 reply
  • 74 views

Userlevel 1
Badge

Does CDataFireDACComponentsforExcel2022 support batch insert to a sheet?
If so, how to use it?

I am using Delphi + FireDac + CDataExcel + SQLServer.

From a stored procedure that returns two DataSets I need to create an excel file with those two DataSets (worksheets).

Previously I have managed to use a batch insert from CSV files to SQL Server; but I have not been able to do the same from a dataset to an excel sheet.

 

I tried this but it throws this exception:

[FireDAC][Phys][CDataExcel]-303. Capability is not supported

    FDQuery1.Connection.StartTransaction;
FDQuery1.Params.ArraySize := 3;

FDQuery1.Params[0].AsStrings[0] := '66666666-269a-491f-ae3a-86ff85149e03';
FDQuery1.Params[1].AsStrings[0] := 'A666666666';
FDQuery1.Params[2].AsStrings[0] := '2023-05-02';
FDQuery1.Params[3].AsFloats[0] := 666666.7895;

FDQuery1.Params[0].AsStrings[1] := '77777777-269a-491f-ae3a-86ff85149e03';
FDQuery1.Params[1].AsStrings[1] := 'A777777777';
FDQuery1.Params[2].AsStrings[1] := '2023-05-03';
FDQuery1.Params[3].AsFloats[1] := 777777.8901;

FDQuery1.Params[0].AsStrings[2] := '88888888-269a-491f-ae3a-86ff85149e03';
FDQuery1.Params[1].AsStrings[2] := 'A888888888';
FDQuery1.Params[2].AsStrings[2] := '2023-05-04';
FDQuery1.Params[3].AsFloats[2] := 888888.9012;

FDQuery1.ExecSQL;
FDQuery1.Connection.Commit;

{ Project CDataCreateXLSX.exe raised exception class EAssertionFailed with message
'[FireDAC][Phys][CDataExcel]-303. Capability is not supported (...)'.
}
// Edit 1, fix typo

If the answer is no; the next approach is the right one to insert all the records into the excel sheet? I tried this with a small dataset to insert each record, not the best option as it is going to be a few thousand records:


conToExcel.ExecSQL
(format('EXEC CreateWorksheet file = %s, sheet = %s, Columnnames = %s',
[QuotedStr('E:/CData/New1.xlsx'), QuotedStr('Report1')
, QuotedStr('NSS, Name, Field3, Field4')
]));

FDQTestReport1.Open; // query for test...
Count := 0;
if FDQTestReport1.RecordCount > 0 then
begin
LogTo(format('%d',[FDQTestReport1.RecordCount]));
FDQuery1.Connection.Params.Values['Header'] := 'true';
FDQuery1.SQL.Text := 'insert into Report1 (NSS, Name, Field3, Field4) values (:f1,:f2,:f3,:f4)';

while not FDQTestReport1.Eof do
begin
FDQuery1.Params.ParamByName('f1').AsString := FDQTestReport1.FieldByName('NSS').AsString;
FDQuery1.Params.ParamByName('f2').AsString := FDQTestReport1.FieldByName('Name').AsString;
FDQuery1.Params.ParamByName('f3').AsString := FDQTestReport1.FieldByName('Field3').AsString;
FDQuery1.Params.ParamByName('f4').AsString := FDQTestReport1.FieldByName('Field4').AsString;
FDQuery1.ExecSQL;
FDQTestReport1.Next;
inc(Count);
end;
end;
FDQuery1.Close;
conToExcel.Close; // flush to disk

Regards

icon

Best answer by Elizabeth G 16 May 2023, 15:49

View original

1 reply

Userlevel 4
Badge

Thank you for reaching out. The Excel drivers do not appear to be able to perform batch inserts. As shown below, the CSV driver has an 'batch processing' section in its documentation, showing how to perform batch inserts. The Excel driver, however, does not have this capability listed, and is unable to perform batch inserts.

CSV: https://cdn.cdata.com/help/RVH/fire/pg_FIREbatch.htm
Excel: https://cdn.cdata.com/help/RXH/fire/pg_usagef.htm

Because of this, it does seem that the only workaround is to insert the records individually.

Reply