如何检测ApplyUpdates是否会插入或更新数据?

时间:2009-07-08 07:51:12

标签: delphi dbexpress tclientdataset

在ClientDataSet的AfterPost事件处理程序中,如果当前记录的ApplyUpdates函数将执行更新或插入,我需要这些信息。

将对新记录和更新记录执行AfterPost事件,我不想声明一个新的Flag变量来指示“更新”或“插入”操作是否正在进行中。

示例代码:

procedure TdmMain.QryTestAfterPost(DataSet: TDataSet);
begin
  if IsInserting(QryTest) then
     // ShowMessage('Inserting')...
  else
     // ShowMessage('Updating');

  QryTest.ApplyUpdates(-1); 
end;

应用程序将在ApplyUpdate完成后在AfterPost方法中写入日志。所以这个方法是最接近动作的地方,我更喜欢一个完全可以插入到这个事件处理程序中的解决方案。

如何使用ClientDataSet实例QryTest中的信息实现IsInserting函数?

编辑:我将尝试ClientDataSet.UpdateStatus,其解释为here

3 个答案:

答案 0 :(得分:6)

ApplyUpdates不会提供该信息 - 因为它可以是插入,更新和删除。

ApplyUpdates应用存储在Delta阵列上的更改信息。例如,该更改信息可以包含任意数量的不同类型的更改(插入,删除和更新),所有这些更改将应用​​于同一个调用。

在TDatasetProvider上你有BeforeUpdateRecord事件(或类似的东西,睡眠在内存上做有趣的事情:-))。在将每个Delta记录应用于底层数据库/数据集之前调用该事件,因此获取此类信息的位置......但Showmessage将停止应用过程。

编辑:现在我记得还有另一种选择:您可以将Delta分配给另一个clientdataset数据属性,并读取该记录的数据集UpdateStatus。 当然,你需要在做之前做applyupdates ...

var
  cdsAux: TClientDataset;
begin
  .
  . 
  <creation of cdsAux>
  cdsAUx.Data := cdsUpdated.Delta;
  cdsAux.First;
  case cdsAux.UpdateStatus of
    usModified:
      ShowMessage('Modified');
    usInserted:
      ShowMessage('Inserted');
    usDeleted:
      ShowMessage('Deleted'); // For this to work you have to modify  
                              // TClientDataset.StatusFilter  
  end;
  <cleanup code>
end;

答案 1 :(得分:4)

TDataSetProvider上的BeforeUpdateRecord事件定义为:

procedure BeforeUpdateRecord(Sender: TObject;  SourceDS: TDataSet; DeltaDS:
                             TCustomClientDataSet; UpdateKind: TUpdateKind;
                             var Applied: Boolean);

参数UpdateKind说明将对记录执行的操作:ukModify, ukInsert or ukDelete。你可以这样测试:

procedure TSomeRDM.SomeProviderBeforeUpdateRecord(Sender: TObject;
      SourceDS: TDataSet; DeltaDS: TCustomClientDataSet; UpdateKind: TUpdateKind;
      var Applied: Boolean);
begin
  case UpdateKind of
    ukInsert :
         // Process Insert;
    ukModify :
         // Process update
    ukDelete :
         // Process Delete
  end;
end;

注意:此事件签名来自Delphi 7.我不知道它是否在更高版本的Delphi中发生了变化。

答案 2 :(得分:3)

将ClientDataSet.StatusFilter设置为TUpdateStatus值,然后读取ClientDataSet.RecordCount

例如,

 ClientDataSet1.StatusFilter := [usDeleted];
 ShowMessage(IntToStr(ClientDataSet1.RecordCount));

将返回将要执行的Delete查询的数量。

但请注意两件事。将StatusFilter设置为usModified始终包括已修改和未修改的记录,因此您将获取该值的一半(值为4表示将执行2个更新查询)。此外,将StatusFilter设置为[](空集)是恢复到默认视图(修改,未修改和插入)的方式

确保在执行此操作之前已发布任何未发布的更改,否则可能不会考虑未发布的更改。