Search code examples
delphidatasettclientdatasetdelphi-xe7firedac

Copy and return FDDataSet from function in Delphi


I have function that should return FDDataset from FDQuery, but I can't copy dataset to Result, or to another FDDataset. This is my main Code:

procedure TForm1.Button1Click(Sender: TObject);
var: Fix: TFDDataSet;
begin
 Fix.CreateDataSet;
 Fix.CopyDataSet(getFix(1));
end;

and function in another Unit:

function getFix(id: Integer): TFDDataSet;
begin
 FDQuery.SQL.Clear;
 FDQuery.SQL.ADD('SELECT ....');
 ...
 FDQuery.SQL.Open;
 Result.CreateDataSet;
 Result.CopyDataSet(FDQuery.Fields.DataSet);
end;

I get error: "Access violation....".

How can I Copy FDQuery results to another TFDDataSet? Or Should I use TClientDataSet? Is there equivalent in FireDac to TClientDataSet?


Solution

  • There are a couple of errors in your code that need to be corrected.

    First, it appears that TFDDataSet is an abstract class (at least parts of it are), even though that's not indicated in the documentation as far as I can tell. This means that you're not able to create and use it as you're wanting. (The source for FireDAC isn't included with the Professional SKUs of Delphi, so I can't look there to confirm.)

    You can use TFDMemTable instead, which works if you create and use it properly. When a function's Result is an object instance, you have to first Create that object instance before you can use it:

    function getFix(id: Integer): TFDMemTable;
    begin
     FDQuery.SQL.Clear;
     FDQuery.SQL.ADD('SELECT ....');
     ...
     FDQuery.Open;
     Result := TFDMemTable.Create(nil); 
     Result.CopyDataSet(FDQuery.Fields.DataSet);
    end;
    

    BTW, you should probably change the name of your function to remind you that you're also responsible for freeing that dataset after you use it to avoid memory leaks. The proper use, then, would be:

    MyMemTable := getFix(SomeID);
    try
      // Do something with MyMemTable
    finally
      MyMemTable.Free;
    end;