如果用户通过dbgrid更改数据,则不会触发AdoConnection的ExecuteCompleted

时间:2016-05-13 14:08:51

标签: delphi delphi-xe2 ado

如果我执行像

这样的查询
Update Table Set aField = 1 Where tablePk = 1

我可以从AdoConneciton的ExecuteComplete事件中获取受影响的记录计数(RecordsAffected参数)。但是如果我通过dbgrid更改数据,则不会触发ExecuteComplete事件。

如何在dbgrid执行的insert / update / delete命令后获得受影响的记录计数?

1 个答案:

答案 0 :(得分:4)

我不认为在您进行更新时有办法获得受影响的行数, 通过TDBgrid或其他DB-aware组件(如TDBNavigator)插入和删除。原因是DB-aware控件调用TDataSet的Post和Delete方法,并且这些调用覆盖了TAdoCustomDataSet中的InternalPost和InternalDelete。它们的工作方式与通过TAdoQuery的ExecSql方法执行SQL语句的方式完全不同。

按照设计,TDataSet.Post和TDataSet.Delete应该只影响一行,所以如果操作成功,你就知道确实有一行受到了影响。

值得注意的是,虽然对你想要做的事情没什么帮助, 是一种将同一事件处理程序附加到数字的方法 TAdoCustomDataSet共享TAdoConnection的后代,如下面的代码所示:

procedure TForm1.FormCreate(Sender: TObject);
var
  i : Integer;
begin
  for i := 0 to AdoConnection1.DataSetCount - 1 do
    AdoConnection1.DataSets[i].AfterPost := AfterPost;
  AdoQuery1.Open;
  AdoQuery2.Open;
end;

procedure TForm1.AfterPost(DataSet: TDataSet);
var
  Q : TAdoQuery;
begin
  if DataSet is TAdoQuery then begin
    Q := TAdoQuery(DataSet);
    Caption := IntToStr(Q.RowsAffected);
  end
  else
    Caption := 'Post';
end;

当然,如果涉及的数据集已经拥有自己的事件处理程序, 你需要一些结构来存储现有的处理程序和链 共享处理程序中的正确的一个(f.i.TForm1.AfterPost上面)。

如果您尝试上述代码并观察发布编辑时会发生什么 从DBGrid获取其来自TAdoQuery的数据,你会发现不幸的是,RowsAffected是零。 这是因为TAdoQuery的FRowsAffected仅在其更新时更新 调用ExecSql方法,并且不会调用数据集操作 通过DBGrid调用。不同之处在于AdoConnection的 从用于执行的OnExecuteComplete对象调用Command TAdoQuery的ExecSql。从DBGrid,otoh,调用启动的操作 与InternalPost和InternalDelete中的TAdoCustomDataSet关联的RecordSet对象的方法, 并且不会调用AdoConnection的OnExecuteComplete

RecordSet个对象有自己的事件集,请参阅f.i. RecordSetEvents 在ADOInt.Pas中,可以想象你可以设置共享事件处理程序 那些与上面的共享AfterPost事件示例类似的方式。然而, 如果你想获得,我不认为这对你有用 从中调用的TDataset插入/更新/删除的RowsAffected值 DBGrid(或者说,TDBNavigator连接到它的TDataSource)。

我说的原因是,如果你看一下源代码 InternalPost的{​​{1}}方法,您会看到它包含

TAdoCustomDataSet

并且嵌套的 if State = dsEdit then UpdateData else begin Recordset.AddNew(EmptyParam, EmptyParam); try UpdateData; except 通过调用

来完成它的工作
UpdateData

现在,如果您查看RecordSet.Update的MS文档,您会看到例如。

  

https://msdn.microsoft.com/en-us/library/ecc2bf09.aspx?f=255&MSPPError=-2147217396

明确指出如果 Recordset.Update(EmptyParam, EmptyParam); 不会影响到一条记录,那么 提出异常。我想这就是@KenWhite在他说的时候想到的 “只会更新一条记录”。所以如果RecordSet.Update成功, 你知道只有一行受到影响。

我没有选中,但由于Update使用了TAdoCustomDataSet.InternalDelete 对象进行删除,类似的情况可能也是如此。