【问题标题】:How to Modify Field Values in TDataSetProvider.OnUpdateData如何修改 TDataSetProvider.OnUpdateData 中的字段值
【发布时间】:2011-06-30 09:24:58
【问题描述】:

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

  1. 检查数据(例如,对于不应允许的值或数据更改),并引发异常以在更新发生之前取消应用。
  2. 在将数据发送到源数据集或数据库服务器之前更改数据(例如加密或解密值)。

我正在寻找有关如何更改 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 中执行 更新前记录/更新后记录。

请指教。非常感谢。

【问题讨论】:

    标签: delphi delphi-xe datasnap


    【解决方案1】:

    不是

    如果 DataSet.UpdateStatus = usUnmodified 然后开始

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

    互斥?你可能有一个错误的结束 - 或者缺少一个 else。

    【讨论】:

    • 是的,它看起来必须互斥,但因为我将此行称为 TPacketDataSet(Dataset).InitAltRecBuffers(True);它将移动到下一条被修改的记录,所以我可以直接编辑该值。
    【解决方案2】:

    好吧,让我们从头开始。

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

    • 已删除和已插入的记录存储仅在 UpdateStatus 上有所不同
      • 1 条记录与各自的状态
    • 已编辑记录的存储方式不同 - 2 条记录以这种方式存储(按此顺序
      • 1 条记录,UpdateStatus = usUnModified
      • 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;
    

    【讨论】:

    • 是的,我确实了解 OnUpdateData 中的顺序,但不知何故,我在修改 usModified 中的字段值时遇到了问题,如示例 1 和示例 2 所示。示例 1 调用 DataSet.Edit 和 DataSet.Post 而有一些提示require字段错误,让我们说一个名为“AutoKey”的必填字段,它只会在usInserted中分配一次,以后不会修改。因此,这可能会在用户下次像示例 1 那样编辑其他字段时触发 Field Value required 错误。例如 2,我们修改 TField.NewValue 但更改未应用于数据库(不起作用)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-24
    • 2020-11-20
    • 2022-01-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多