首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如果用户通过dbgrid更改数据,则不会触发ExecuteCompleted of AdoConnection。

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

Stack Overflow用户
提问于 2016-05-13 14:08:51
回答 1查看 375关注 0票数 2

如果我执行这样的查询

代码语言:javascript
复制
Update Table Set aField = 1 Where tablePk = 1

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

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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-05-14 15:01:05

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

按照设计,TDataSet.Post和TDataSet.Delete应该只影响一行,因此如果操作成功,您就知道只有一行受到了影响。

值得注意的是,尽管对您想要做的事情帮助不大,但,它可以将相同的事件处理程序附加到共享TAdoConnection的许多TAdoCustomDataSet后代,如下面的代码所示:

代码语言:javascript
复制
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.在上面的帖子之后)

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

RecordSet对象有自己的事件集,参见f.i。RecordSetEvents中的ADOInt.Pas,可以想象,您可以为那些类似于上面的共享AfterPost事件示例的人设置共享事件处理程序。但是,如果您希望从RowsAffected调用TDataset Insert/Update/Delete (或者说连接到其TDataSource的TDBNavigator ),那么这对您没有任何帮助。

我这么说的原因是,如果您看一下TAdoCustomDataSetTAdoCustomDataSet方法的源代码,就会发现它包括

代码语言:javascript
复制
  if State = dsEdit then
    UpdateData
  else
  begin
    Recordset.AddNew(EmptyParam, EmptyParam);
    try
      UpdateData;
    except

嵌套的UpdateData通过调用

代码语言:javascript
复制
    Recordset.Update(EmptyParam, EmptyParam);

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

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

其中明确指出,如果Update不影响确切的一条记录,则会引发异常。我想这就是肯怀特所说的“只更新一张唱片”时的想法。因此,如果RecordSet.Update成功,您就知道只有一行受到影响。

我还没有检查,但是由于TAdoCustomDataSet.InternalDelete使用它的Recordset对象来执行删除,类似的情况可能也是如此。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37212197

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档