Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>One would hope sth. like this would work (at least when there are no calculated fields);</p> <pre><code>uses dsintf; [..] procedure TForm1.Button1Click(Sender: TObject); begin ClientDataSet1.First; while not ClientDataSet1.Eof do begin PRecInfo(ClientDataSet1.ActiveBuffer + ClientDataSet1.RecordSize).Attribute := dsRecNew; ClientDataSet1.Next; end; end; </code></pre> <p>Well, it works, but as long as no data is re-retrieved. That is, <code>TCustomClientDataSet.GetRecord</code> re-sets the record attributes. This renders the hacky approach pretty useless I guess.</p> <p>Maybe one could try binding a data-aware control and see if setting the BufferCount of the DataLink of the DataSource would help. Or, try overriding GetRecord in a descendant ClientDataSet. But I doubt it is worth the effort.</p> <p><strong>[EDIT]</strong></p> <p>The record attribute can be <i>hacked</i> in an "AfterScroll" event. This would help, for instance, code testing the UpdateStatus to return "usInserted".</p> <pre><code>procedure TForm1.ClientDataSet1AfterScroll(DataSet: TDataSet); begin PRecInfo(DataSet.ActiveBuffer + DataSet.RecordSize).Attribute := dsRecNew; end; </code></pre> <p>Test if all the records are inserted</p> <pre><code>procedure TForm1.Button1Click(Sender: TObject); begin ClientDataSet1.First; while not ClientDataSet1.Eof do begin if not (ClientDataSet1.UpdateStatus = usInserted) then raise Exception.Create('The record is not inserted'); ClientDataSet1.Next; end; end; </code></pre> <p><br><hr> A new TClientDataSet can be derived to retrieve always "inserted" records.</p> <p>(The type declaration goes <b>before</b> the form/datamoule containing the ClientDataSet)</p> <pre><code>type TClientDataset = class(dbclient.TClientDataSet) function GetRecord(Buffer: PChar; GetMode: TGetMode; DoCheck: Boolean): TGetResult; override; end; [..] implementation function TClientDataset.GetRecord(Buffer: PChar; GetMode: TGetMode; DoCheck: Boolean): TGetResult; begin Result := inherited GetRecord(Buffer, GetMode, DoCheck); if Result = grOk then PRecInfo(Buffer + RecordSize).Attribute := dsRecNew; end; </code></pre> <p>Now for all records, UpdateStatus will return "usInserted".</p> <p><strong>EDIT</strong></p> <p>I finally understood that the aim is to generate insert SQLs for all records. We won't achieve this by modifying records' attributes of the DataSet, ApplyUpdates takes only the "Delta" into consideration and we possibly have no Delta. There might be different ways to achieve this, the below example assumes the DataSet has a Provider and we are able to put an event handler on it.</p> <pre><code>type TForm1 = class(TForm) [..] private procedure DeltaAfterScroll(DataSet: TDataSet); [..] implementation procedure TForm1.DeltaAfterScroll(DataSet: TDataSet); begin // The UpdateTree of the Resolver of the Provider will visit each // record to get the UpdateStatus PRecInfo(DataSet.ActiveBuffer + DataSet.RecordSize).Attribute := dsRecNew; end; type TAccessCCDS = class(TCustomClientDataSet); procedure TForm1.Button1Click(Sender: TObject); var Count: Integer; begin ClientDataSet1.MergeChangeLog; // Since there's no "Delta", ApplyUpdates will return immediately. // Hence, we'll force an update by calling DoApplyUpdates, bypassing the // ChangeCount test, and update with the "Data". // Reconcilation is left out for simplicity. TAccessCCDS(ClientDataSet1).DoApplyUpdates(ClientDataSet1.Data, 0, Count); end; procedure TForm1.DataSetProvider1UpdateData(Sender: TObject; DataSet: TCustomClientDataSet); begin // Will be called once when ApplyUpdates is called. TAccessCCDS(DataSet).AfterScroll := DeltaAfterScroll; end; </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload