在使用TClientDataSet的ApplyUpdates之后获取触发器生成的值

时间:2012-08-21 02:41:24

标签: delphi delphi-xe2 firebird datasnap tclientdataset

我有一个(Firebird)数据库。对于我的大多数表格,我有一个触发器,它在插入之前触发,它将通过生成器为我创建主键(PK),并向新插入的记录写入创建日期值和创建者值。我还有一个更新触发器,它写入更新日期字段和更新者字段。

例如(客户端是我的数据库中的表):

create trigger t_client_id for client
active before insert
as begin
  new.client_id = gen_id(gen_client_id, 1);
  new.created = current_timestamp;
  new.created_by = current_user;
  new.lock_vn = 1;
end ^

create trigger t_client_update for client
active before update
as begin
  new.updated = current_timestamp;
  new.updated_by = current_user;
end ^   

当我通过我的ClientDataSet(CDS)应用更新(通过TDSProviderConnection附加到远程TDataSetProviders)时,如何“检索”这些生成的值?如果我编辑一个现有的(它将依次调用t_client_update触发器,调用RefreshRecord将获得更新和updated_by字段。但是,Doco说要谨慎使用该方法,因此这可能不是实现此目的的正确方法。我在我调用ApplyUpdates(-1)之后直接调用它。

我使用的CDS只包含我尝试编辑的一条记录。对于新记录,CDS处于dsInsert模式。一切都写入数据库确定,所以我只需要重新获得这些新数据。我也尝试过使用包含表中所有记录的CDS来查看它是否更简单但没有任何区别 - 毫不奇怪。我需要此信息的原因只是向DB Aware中的用户显示控制这些值。它们是只读的。

我可以在使用PK编辑现有记录时调用记录中的Get,但这对插入没有帮助,因为我不知道新PK是什么。

我尝试将ApplyUpdates应用到我的CDS的示例(actDSSave是一个TDataSetPost操作)

  dsState := actDSSave.DataSource.DataSet.State;
  DoApplyUpdates(-1);
  if dsState = dsEdit then
    TClientDataSet(actDSSave.DataSource.DataSet).RefreshRecord;

我正在将TIBQuery用于附加到远程DataSetProvider的数据集。此查询SQL是一个简单的 select * from client,其中client_id =:client_id 。我已尝试将此查询与TIBUpdateSQL相关联,并尝试在DataSetProvider中将poAutoRefresh设置为true。

因此可以通过这种方式获取这些触发器生成的值,还是需要以不同的方式处理它?我能想到的另一种方法是创建存储过程,对每个表执行CRUD并使用它(使用适当的输入/输出参数来返回这些新数据),但希望我不必走这条轨道。希望我在这里提供了足够的信息来解释和复制问题。

由于

修改 在上面实现,DoApplyUpdates(-1)是我自己的方法。目前它的实施很简单:

FdatCommon.cdsClient.ApplyUpdates(MaxErrorCount);

FdatCommon是一个包含我的CDS的TDataModule。

1 个答案:

答案 0 :(得分:0)

如果没有Post后的新的requery(RefreshRecord)数据,你就无法获得“生成”的值。

这是因为当您调用ApplyUpdates时触发器在服务器端运行,但TClientDataSet默认情况下不会刷新已发布的记录。例如,其他库FIBPlus可以选择自动执行。

关于插入,TIBDataSet具有GeneratorField属性。在插入之前单独使用它,数据集查询和增量生成器值。因此,即使在插入后,您也会获得PK值。但请避免在触发器中再次使用它。

MIDAS(TClientDataSet)是一个很棒的库,但是他的通用/通用架构与特定DBMS的专用库(如FibPlus)相比,松散了DB特定的功能(例如从插入中重新获取值)。顺便说一下,我看到了TpFIBClientDataSet。它与TpFibDataSet一起使用。