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



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

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

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)应用更新时,我如何"检索"这些生成的值?如果我编辑一个现有的方法(它反过来会调用t_client_update触发器,调用RefreshRecord会得到updated和updated_by字段。然而,Doco说要谨慎使用该方法,所以这可能不是实现这一点的正确方法。我在调用ApplyUpdates(-1)后直接调用它。

我使用的CDS只包含我试图编辑的一条记录。对于新记录,CDS处于dsInsert模式。所有的东西都写进了数据库,所以我只需要再次把这些新数据拿出来。我还尝试过使用CDS,它也包含表中的所有记录,看看它是否更简单,但没有任何区别——这并不奇怪。我需要这些信息的原因只是为了在DB Aware控件中向用户显示这些值。它们是只读的。

我想在编辑现有记录时,我可以使用PK来调用Get on the record,但这对Insert没有帮助,因为我不知道新的PK是什么。

我尝试将更新应用到CDS的示例(actDSSave是TDataSetPost操作)

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

我正在对连接到远程DataSetProvider的数据集使用TIBCQuery。此查询SQL是一个简单的从客户端选择*,其中client_id=:client_id。我也尝试将此查询与TIBUpdateSQL关联,并尝试在DataSetProvider中将poAutoRefresh设置为true。

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

感谢

编辑如上所述,DoApplyUpdates(-1)是我自己的方法。目前它的实现很简单:

FdatCommon.cdsClient.ApplyUpdates(MaxErrorCount);

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

Post之后,如果没有新的数据查询(RefreshRecord),就无法获得"生成的"值。

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

关于插入,TIBDet具有GeneratorField属性。使用它,数据集查询和增量生成器值分别在插入之前。所以你会有PK值后张贴甚至插入。但要避免在触发器中再次使用它。

MIDAS(TClientDataSet)是一个很棒的库,但与用于特定DBMS的专用库(如FibPlus)相比,他的通用/通用体系结构缺少特定于DB的功能(如从插入中检索值)。顺便说一下,我看到了TpFIBClientDataSet。它与TpFibDataSet协同工作。

最新更新