Delphi 使用TClientDataSet进行ApplyUpdate后获取触发器生成的值

Delphi 使用TClientDataSet进行ApplyUpdate后获取触发器生成的值,delphi,delphi-xe2,firebird,datasnap,tclientdataset,Delphi,Delphi Xe2,Firebird,Datasnap,Tclientdataset,我有一个(火鸟)数据库。对于我的大多数表,我有一个触发器,在插入之前触发,它将通过生成器为我创建主键(PK),并向新插入的记录写入一个Created Date值和一个Created By值。我还有一个更新触发器,它写入更新日期字段和更新人字段 例如(客户是我数据库中的一个表): 当我通过ClientDataSet(CD)应用更新时(CD通过TDSProviderConnection连接到远程TDatasetProvider),我如何“检索”这些生成的值?如果我编辑一个现有的方法(这将反过来调用t

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

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

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

我使用的CD只包含我正试图编辑的一条记录。对于新记录,CD处于dsInsert模式。所有内容都写入DB ok,因此我只需要重新获取这些新数据。我还尝试使用包含表中所有记录的CD,以查看它是否更简单,但没有任何区别-取消我之所以需要这些信息,只是为了在DB Aware控件中向用户显示这些值。它们是只读的

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

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

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

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

谢谢

编辑 DoApplyUpdates(-1)是我自己的方法,在上面已经实现。目前它的实现只是:

FdatCommon.cdsClient.ApplyUpdates(MaxErrorCount);
FdatCommon是一个包含我的CD的TDataModule。

如果Post后没有新的数据重新查询(刷新记录),您就无法获得“生成的”值

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

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


MIDAS(TClientDataSet)是一个很棒的库,但他的通用/通用体系结构松散了特定于DB的特性(例如从插入中检索值)与特定DBMS的专用库(如FibPlus)相比,我看到的是TpFIBClientDataSet。它与TpFibDataSet一起工作。

对于insert,您可能需要进行单独的查询,既添加新行又返回生成的值?对于Firebird 2.1及更高版本,您可以在
insert
语句中使用该子句。如果我想我可以使用TDatasetProvider和TClientDataSet来利用这一功能——我很乐意在编辑/插入后调用GET-About。
  dsState := actDSSave.DataSource.DataSet.State;
  DoApplyUpdates(-1);
  if dsState = dsEdit then
    TClientDataSet(actDSSave.DataSource.DataSet).RefreshRecord;
FdatCommon.cdsClient.ApplyUpdates(MaxErrorCount);