如果我执行这样的查询
Update Table Set aField = 1 Where tablePk = 1我可以从RecordsAffected的ExecuteComplete事件中获得受影响的记录计数( AdoConneciton参数)。但是,如果我通过dbgrid更改数据,则不会触发ExecuteComplete事件。
如何在dbgrid执行insert/update/delete命令后得到受影响的记录计数?
发布于 2016-05-14 15:01:05
我不认为在您通过TDBgrid或其他支持数据库的组件(如TDBNavigator )进行更新、插入和删除时,会得到受影响的行数。原因是基于DB的控件调用TDataSet的Post和Delete方法,而这些调用覆盖了TAdoCustomDataSet中的InternalPost和InternalDelete。它们的工作方式与通过(例如,ExecSql )的TAdoQuery方法执行SQL语句的方式完全不同。
按照设计,TDataSet.Post和TDataSet.Delete应该只影响一行,因此如果操作成功,您就知道只有一行受到了影响。
值得注意的是,尽管对您想要做的事情帮助不大,但是,它可以将相同的事件处理程序附加到共享TAdoConnection的许多TAdoCustomDataSet后代,如下面的代码所示:
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的OnExecuteComplete的Command对象调用AdoConnection的ExecSql。从DBGrid启动的操作,otoh,调用与TAdoCustomDataSet关联的InternalPost和InternalDelete中的RecordSet对象的方法,并且不调用AdoConnection的OnExecuteComplete。
RecordSet对象有自己的事件集,参见f.i。RecordSetEvents中的ADOInt.Pas,可以想象,您可以为那些类似于上面的共享AfterPost事件示例的人设置共享事件处理程序。但是,如果您希望从RowsAffected调用TDataset Insert/Update/Delete (或者说连接到其TDataSource的TDBNavigator ),那么这对您没有任何帮助。
我这么说的原因是,如果您看一下TAdoCustomDataSet的TAdoCustomDataSet方法的源代码,就会发现它包括
if State = dsEdit then
UpdateData
else
begin
Recordset.AddNew(EmptyParam, EmptyParam);
try
UpdateData;
except嵌套的UpdateData通过调用
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对象来执行删除,类似的情况可能也是如此。
https://stackoverflow.com/questions/37212197
复制相似问题