4

By default, the TClientDataSet tracks all the changes made in the DataSet (inserts, updates, deletes). Is there a way to tell the dataset to accept the current changes (after a series of inserts using insert/post, let's say) without actually calling the database to save anything?

One idea that I thought of was to use a TDataSetProvider and implement the BeforeUpdateRecord event and set the Applied parameter to true. I don't like two things about this. I have to add two more objects (TDataSetProvider and the TSQLQuery object) and ApplyUpdates starts a transaction. Is there a simpler way?

If I don't set the ProviderName on the TClientDataSet, ApplyUpdates fails.

Thanks

boggy
  • 3,674
  • 3
  • 33
  • 56
  • Set LogChanges to false before inserting, or call MergeChangeLog. Or I haven't understood.. – Sertac Akyuz Mar 06 '14 at 02:25
  • @SertacAkyuz: That's it. Please answer so I can accept your answer as the solution. – boggy Mar 06 '14 at 02:49
  • @Sertac: Looks like you actually beat me to it. If you post an answer that includes that information, I'll delete mine. (I saw the question and the only answer, but didn't read the comments to either before posting. The answer is rightfully yours.) – Ken White Mar 06 '14 at 03:09
  • possible duplicate of [Delphi - applying Delta to a TClientDataSet](http://stackoverflow.com/questions/21510326/delphi-applying-delta-to-a-tclientdataset) – Sir Rufo Mar 06 '14 at 08:16
  • @Ken - Done. Thanks for that, actually you don't have to watch for the comments before answering. – Sertac Akyuz Mar 06 '14 at 08:37

3 Answers3

5

You can set LogChanges to false before modifying the dataset. Alternatively, if you need the change log at any stage, you can call MergeChangeLog to incorporate updates.

Sertac Akyuz
  • 54,131
  • 4
  • 102
  • 169
1

Be aware that there is a bug (at least still in D2006) that may cause you a great headache: If LogChanges is False, some of the filter functionality is not working correctly: Records may remain inside a filtered dataset even if their values do not match the given filter criteria.

See this unit test:

  procedure TestCDS.TestLogChanges;
  var CDS: TClientDataset;
  begin
     CDS := TClientDataset.Create(NIL);
     try
        CDS.FieldDefs.Add('MyStringField', ftString, 20 );
        CDS.CreateDataSet;
        try
           CDS.LogChanges := False;
           CDS.Filter := 'MyStringField is null';
           CDS.Filtered := True;
           Check( CDS.RecordCount= 0);
           CDS.Insert;
           CDS.Post;
           Check( CDS.RecordCount= 1);
           CDS.Edit;
           CDS.FieldByName('MyStringField').AsString := 'Text';
           CDS.Post;
           Check( CDS.RecordCount= 0, 'Recordcount is not 0 after changing value!');
        finally
           CDS.Close;
        end;
     finally
        CDS.Free;
     end;
  end;

Also have a look here, it obviously is an older bug: http://www.delphigroups.info/2/f0/463155.html

Udontknow
  • 1,472
  • 12
  • 32
0

I use it that way. I load it with data from a database and then send the data to a FastReports instance or to PDF forms or an Excel spreadsheet. It makes it possible for me to use one process to produce all my different kinds of output. It has been a while since I set it up but I think I set it up the way you are describing.

jrodenhi
  • 2,237
  • 1
  • 21
  • 31
  • Sorry. I probably missed your point. It sounds like Sertac gave you what you needed anyway. Hopefully he will come back and make his response an answer. – jrodenhi Mar 06 '14 at 03:04