After reading the Delphi help file about TDataSetProvider.OnUpdateData event explanation:
- Examine data (for example, for values or data changes that should not permitted), and raise exceptions that cancel applying of updates before they occur.
- 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.
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.
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;
来源:https://stackoverflow.com/questions/6532671/how-to-modify-field-values-in-tdatasetprovider-onupdatedata