Firebird更新或使用生成的密钥插入

时间:2018-12-05 17:12:54

标签: delphi firebird firedac

在Delphi 10.2 w / FireDAC下使用Firebird 2.5:我有一个表,其中包含事件处理程序对象的定义数据,以及从表中加载和存储的那些对象的TObjectList-该表永远不会变得很大,也许最大30-40行,通常只有极少数。该表的每一行都有一个由插入后触发器生成的PK。我需要能够将对象更新回匹配的表行,并插入任何新条目 并在插入后获取生成的PK值,以保持对象的ID匹配。

Firebird支持的UPDATE OR INSERT子句似乎不适用于由插入后触发器生成PK的情况,但也许我遗漏了一些东西。

那么,有没有一种直接的方式来进行这种构造?考虑到表的大小,仅更改表并插入所有新记录是否会更有效率(如果不是完全符合犹太标准)?

1 个答案:

答案 0 :(得分:0)

UPDATE OR INSERT语句支持RETURNING子句,该子句允许您返回生成的ID。

但是,主要问题是您说“其中PK是由插入后触发器生成的” 。这是不可能的,或者-至少-如果您现在正在这样做,则说明您没有以正确的方式进行操作,并且很可能在表上使用了update语句之类的解决方法。

生成ID的正确方法是在“插入之前”触发器中,该触发器的值在NEW上下文(例如NEW.id = <generated value>)上设置。 “插入后”触发器无法修改NEW上下文,因此无法以正确的方式更新列值。在'before insert'触发器中更新NEW上下文中的值也是使它可以使用RETURNING子句返回的原因。

另请参阅Firebird语言参考中的"OLD and NEW Context Variables"

  

在所有AFTER触发代码中,NEW变量是只读的

您可能还想阅读CREATE TRIGGER文档,其中还包括有关如何生成ID的示例。有关另一个示例,请参见How to create an autoincrement column?