如何在TDataSetProvider.OnUpdateData中修改字段值

时间:2011-06-30 09:24:59

标签: delphi delphi-xe datasnap

阅读有关TDataSetProvider.OnUpdateData的Delphi帮助文件后 事件说明:

  1. 检查数据(例如,对于不应允许的值或数据更改),并引发在更新发生之前取消应用更新的异常。
  2. 在将数据发送到源数据集或数据库服务器之前更改数据(例如加密或解密值)。
  3. 我正在寻找如何为OnUpdateData 更改数据的示例代码。 我尽力寻找解决方案。这就是我能做到的:

    示例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;
    

    示例1的问题:不幸的是,我一直收到一些字段值丢失的错误。执行一些调试后,我发现有必要的字段具有空值。

    示例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;
    

    示例2的问题:通过这种方式编写,我们无需调用DataSet.Edit& DataSet.Post。但设置为TField.NewValue的值'zzz'未保存到数据库中。

    我有一些特殊原因,此更新必须在OnUpdateData中执行 of BeforeUpdateRecord / AfterUpdateRecord。

    请指教。非常感谢你。

2 个答案:

答案 0 :(得分:0)

不是

如果DataSet.UpdateStatus = usUnmodified则开始

如果[usInserted,usModified]中的DataSet.UpdateStatus那么

相互排斥?你可能有一个错位的结局 - 或者没有别的。

答案 1 :(得分:0)

好吧,让我们从头开始。

在delta中,记录了修改(根据我的经验):

  • 已删除和插入的记录存储仅在UpdateStatus上有所不同
    • 具有相应状态的1条记录
  • 编辑记录以不同方式存储 - 以这种方式存储2条记录( IN THAT ORDER
    • 使用UpdateStatus = usUnModified
    • 的1条记录
    • 使用UpdateStatus = usModified的1条记录 - 此记录仅 已修改字段的值。另一个字段都是空的。

如何进行Delta修改

对于已插入/已删除的记录

将StatusFilter设置为[usInserted]和/或[usDeleted]。改变他们。你已经完成了。

修改记录

将SetStatusFiler设置为[usUnModified,usModified]以查看Delta中的两个记录。 做一个While not DSDelta.Eof do并为每个UpdateStatus = usUnModified做你的 测试。如果是,则在下一条记录中继续修改(UpdateStatus = usModified对应于您测试的记录)。否则,您使用UpdateStatus = usUnModified来查找下一条记录。

编辑:你是对的。如果您不包含所有标记为必需的字段,则无法更改已修改记录的增量字段。

你的代码是:

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;