Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: Problems using MergeDataSet to add field to existing TFDMemTable


This question is not answered. Helpful answers available: 2. Correct answers available: 1.


Permlink Replies: 0
Jay Daley

Posts: 8
Registered: 8/16/12
Problems using MergeDataSet to add field to existing TFDMemTable  
Click to report abuse...   Click to reply to this thread Reply
  Posted: May 10, 2017 3:08 AM
I've been trying to understand how to add a field to a TFDMemTable using MergeDataSet and I've run into a few problems. To start assume we have an FDConnection and a TFDMemTable called FTable on a form, to which we load a few records:
Snippet 1
begin
  with FTable.FieldDefs.AddFieldDef do        // add the field to the TFDMemTable
  begin
    Name := 'id';
    DataType := ftInteger;
  end;
  with FTable.FieldDefs.AddFieldDef do        // add the field to the TFDMemTable
  begin
    Name := 'cap';
    DataType := ftString;
    Size := 20;
  end;
  FTable.CreateDataSet;
  FTable.Open;
 
  with FTable do
  begin
    Append;
    Fields[0].AsInteger := 1;
    Fields[1].AsString := 'one';
    Post;
  end;
end;


The data is now

|id|cap|
| 1|one|


The recommended way to add a new field is given in the TFDMemTable sample and basically as follows:
Snippet 2
var
  mt: TFDMemTable;
begin
  mt := TFDMemTable.Create(nil);
  try
    mt.Data := FTable.Data;                                   // temporarily hold the data
    FTable.Close;                                             // now close the main table
    with FTable.FieldDefs.AddFieldDef do begin                // add the new field
      Name := 'new2';
      DataType := ftString;
      Size := 20;
    end;
 
    with FTable do begin
      Open;                                                   // re-open the main table
      MergeDataSet(mt, dmDataSet, mmNone);                    // merge the data back in
      if Active then if not FieldDefs.Updated then FieldDefs.Update;
    end;
  finally
    mt.Free;
  end;
end;


That works but takes so long on a large (~2m records) dataset that I've never left it to complete. So instead I tried some alternatives. The first is the most obvious, create a new dataset, add a field to it and then merge that into the original:
Snippet 3
var
  mt: TFDMemTable;
begin
  mt := TFDMemTable.Create(nil);
  with mt.FieldDefs.AddFieldDef do begin
    Name := 'new3';
    DataType := ftString;
    Size := 20;
  end;
  mt.CreateDataSet;
  mt.Open;
 
  with FTable do begin
    MergeDataSet(mt, TFDMergeDataMode.dmNone, TFDMergeMetaMode.mmMerge);
    if not FieldDefs.Updated then FieldDefs.Update;
  end;
  mt.Free;
end;


BUT doing this does not add the field and it removes all the records from the original TFDMemTable. To makes things odder, even though the newly created temporary TFDMemTable has no records in it I found that if I use TFDMergeDataMode.dmDataAppend instead of TFDMergeDataMode.dmNone then the records are not lost, though the field is still not added.

So my first question is 1) Is this a bug or is MergeDataSet with TFDMergeDataMode.dmNone meant to delete all the records from the target dataset?

Having managed to keep the data during the merge but not have the field copied over I thought I might try adding some data before doing the merge to see what difference that makes:
Snippet 4
var
  mt: TFDMemTable;
begin
  mt := TFDMemTable.Create(nil);
  with mt.FieldDefs.AddFieldDef do begin
    Name := 'new4';
    DataType := ftString;
    Size := 20;
  end;
  mt.CreateDataSet;
  mt.Open;
 
  with mt do
  begin
    Append;
    Fields[0].AsString := 'test';
    Post;
  end;
 
  with FTable do begin
    MergeDataSet(mt, TFDMergeDataMode.dmDataAppend, TFDMergeMetaMode.mmMerge);
    if not FieldDefs.Updated then FieldDefs.Update;
  end;
  mt.Free;
end;


The unusual thing is that the target dataset has indeed had another record added to it, but it appears blank because the new field has not been added. Assuming we did this after snippet 1 the data now looks like:

|id|cap|
| 1|one|
|  |   |


Now it gets really weird.

If I now add another field (new2) using the recommended method of snippet 2 above then the missing field added in snippet 4 (new4) also appears (so it's as if two fields are added not just one by this method) AND the data I added also magically appears. So the data now looks like

|id|cap|new4|new2|
| 1|one|    |    |
|  |   |test|    |


So my second question is 2) What is going on here? Is there a bug here or is this intended behaviour?
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02