如果我执行像
这样的查询Update Table Set aField = 1 Where tablePk = 1
我可以从AdoConneciton的ExecuteComplete事件中获取受影响的记录计数(RecordsAffected参数)。但是如果我通过dbgrid更改数据,则不会触发ExecuteComplete事件。
如何在dbgrid执行的insert / update / delete命令后获得受影响的记录计数?
答案 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
对象进行删除,类似的情况可能也是如此。