0

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?

Gem
  • 516
  • 1
  • 8
  • 19

1 Answers1

3

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;
Ken White
  • 123,280
  • 14
  • 225
  • 444
  • I did try like that and got "Abstract Error" and was looking here http://stackoverflow.com/a/18669138/2980912, so maybe I can't use TFDDataSet like this? Or that doesn't matter? – Gem Dec 19 '14 at 17:21
  • When you step through the code, which line causes the Abstract Error? – Ken White Dec 19 '14 at 17:41
  • Lines CreateDataSet and CopyDataSet causes error... I was trying to pass FDQuery results outside of that function and parse values from it. I did it by creating Records (array of Record) but I was told that this is better way because of sorting and stuff... Maybe some other way to do that? Call that function, query sql and get back results to read them outside function in another one? Maybe FDMemTable or ClientDataSet? – Gem Dec 19 '14 at 17:57
  • See my edited answer for a working solution using `TFDMemTable`. – Ken White Dec 19 '14 at 18:25
  • In this case I would go for the "simpler" solution : Result.Data := FDQuery.Data; // replacing the CopyDataSet method. This is much faster - and auto populates the fields. – Bimmer_R Jan 28 '15 at 12:08