1

After reading the Delphi help file about TDataSetProvider.OnUpdateData event explanation:

  1. Examine data (for example, for values or data changes that should not permitted), and raise exceptions that cancel applying of updates before they occur.
  2. Change data (for example encrypting or decrypting values) before it is sent on to the source dataset or database server.

I am looking for a sample code of how to change data for OnUpdateData. I have tried my best to look for solution. This is what I can achieve:

Example 1:

procedure TDBNextDocNo.DSPUpdateData(Sender: TObject; DataSet: TCustomClientDataSet);
begin
  DataSet.First;
  while not DataSet.EOF do begin
    if DataSet.UpdateStatus = usUnmodified then begin
      TPacketDataSet(Dataset).InitAltRecBuffers(True);
      if DataSet.UpdateStatus in [usInserted, usModified] then begin
        Dataset.Edit;
        DataSet.FindField('MyField').AsString := 'zzz';
        Dataset.Post;
      end;
    end;
  end;
  DataSet.Next;
end;

Problem for Example 1: Unfortunately, I keep receive error that some field value is missing. After perform some debug, I found that there are required fields that has empty value.

Example 2:

procedure TDBNextDocNo.DSPUpdateData(Sender: TObject; DataSet: TCustomClientDataSet);
begin
  DataSet.First;
  while not DataSet.EOF do begin
    if DataSet.UpdateStatus = usUnmodified then begin
      TPacketDataSet(Dataset).InitAltRecBuffers(True);
      if DataSet.UpdateStatus in [usInserted, usModified] then 
        DataSet.FindField('MyField').NewValue:= 'zzz';     
    end;
    DataSet.Next;
  end;  
end;

Problem for Example 2: By writing this way we no need to call DataSet.Edit & DataSet.Post. But the value 'zzz' which set to TField.NewValue is not being saved into database.

I have some special reason that the this update must perform in OnUpdateData instead of BeforeUpdateRecord/AfterUpdateRecord.

Please advice. Thank you very much.

Chau Chee Yang
  • 18,422
  • 16
  • 68
  • 132
Sherlyn
  • 41
  • 1
  • 3

2 Answers2

0

Aren't

if DataSet.UpdateStatus = usUnmodified then begin

and

if DataSet.UpdateStatus in [usInserted, usModified] then

Mutually exclusive? You may have a misplaced end - or lack of an else.

  • Yes it looks like have to mutually exclusive but since i call this line TPacketDataSet(Dataset).InitAltRecBuffers(True); It will move to next record which is usModified, so I can directly edit the value. – Sherlyn Jul 01 '11 at 01:21
0

Well, let's start from beginning.

In delta, modifications are recorded (in my experience with it):

  • Deleted and Inserted records storage differ only on UpdateStatus
    • 1 record with the respective status
  • Edited record are stored differently - 2 records are stored that way (and IN THAT ORDER)
    • 1 record with UpdateStatus = usUnModified
    • 1 record with UpdateStatus = usModified - this record have only the values of the modified fields. The other field are all empty.

How to proceed an Delta modification

For Inserted/Deleted records

Set StatusFilter to [usInserted] and/or [usDeleted]. Alter they. You're done.

For Modified Records

Set SetStatusFiler to [usUnModified,usModified] to see both records in Delta. Do a While not DSDelta.Eof do and for each UpdateStatus = usUnModified do your test. If yes, you proceed with modification in the next record (the UpdateStatus = usModified corresponding to the one you tested). Else, you look for the next record with UpdateStatus = usUnModified.

EDIT: You're right. There's no way to change an field on delta of a modified record if you doesn't include all the fields that are marked required.

You're code goes to:

procedure TDBNextDocNo.DSPUpdateData(Sender: TObject; DataSet: TCustomClientDataSet);
begin
  DataSet.First;
  while not DataSet.EOF do begin
    if DataSet.UpdateStatus = usUnmodified then begin
      TPacketDataSet(Dataset).InitAltRecBuffers(True);
      if DataSet.UpdateStatus in [usInserted, usModified] then begin
        Dataset.Edit;
        DataSet.FindField('MyField').AsString := 'zzz';

        If Dataset.UpdateStatus in [usModified] then
        begin
          for i = 0 to Dataset.FieldCount - 1 do
          begin
            If Dataset.Fields[i].Name <> 'MyField' then
            begin
              If Dataset.Fields[i].Required then
                Dataset.Fields[i].Value := Dataset.Fields[i].OldValue; 
            end; 
          end;
        end;
        Dataset.Post;
      end;
    end;
  end;
  DataSet.Next;
end;
Fabricio Araujo
  • 3,810
  • 3
  • 28
  • 43
  • Yes i do understand the order in OnUpdateData, but somehow i face problem to modify field values in usModified as in example 1 and example 2. Example 1 call DataSet.Edit and DataSet.Post while there is some require field error prompted, let said a required field called "AutoKey" it will be assigned once in usInserted only and will not be modified in future. Thus this might trigger Field Value required error when user edit other fields next time like example 1. For example 2, we modify TField.NewValue but the changes does not applied to database (not working) – Sherlyn Jul 01 '11 at 03:44