在Delphi 10.2 w / FireDAC下使用Firebird 2.5:我有一个表,其中包含事件处理程序对象的定义数据,以及从表中加载和存储的那些对象的TObjectList-该表永远不会变得很大,也许最大30-40行,通常只有极少数。该表的每一行都有一个由插入后触发器生成的PK。我需要能够将对象更新回匹配的表行,并插入任何新条目 并在插入后获取生成的PK值,以保持对象的ID匹配。
Firebird支持的UPDATE OR INSERT子句似乎不适用于由插入后触发器生成PK的情况,但也许我遗漏了一些东西。
那么,有没有一种直接的方式来进行这种构造?考虑到表的大小,仅更改表并插入所有新记录是否会更有效率(如果不是完全符合犹太标准)?
答案 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?。