【发布时间】:2016-06-06 16:09:39
【问题描述】:
我尝试使用删除和更新触发器记录对 DB2 表的更改。 让我们假设一个简单的例子:一个人有一个地址。日志表不仅应包含人员数据,还应包含地址表中的一些值。
所以表格是 PERSON (ID, NAME) 和 ADDRESS(PERSON_ID, STREET, ...)
这是我尝试设置的:
CREATE TRIGGER log_history
AFTER UPDATE OR DELETE ON person
REFERENCING OLD AS O
FOR EACH ROW MODE DB2SQL
BEGIN
DECLARE street VARCHAR(150);
SET street = (SELECT street from ADDRESS join person on ADDRESS.person_id=O.id);
INSERT INTO LOG(id,name,street) VALUES(O.id, O.name, street);
END
更新被完美记录。我看到所有旧值都插入到日志表中,包括街道。
对于 DELETE 操作,日志行仅包含 PERSON 表的值,但 STREET 列对于已删除的行为 NULL。
我还尝试使用 BEFORE 触发器,并尝试使用简单的 where 子句加入。结果总是一样的。
我可能应该提到,当您删除 PERSON 时,有一个 ON DELETE CASCADE FK 会删除 ADDRESS。但是,我的理解是删除该依赖表(地址 ) 发生在触发器之后...
我在 Linux 服务器上使用 DB2 10.5 LUW(应该不相关,但是...)
那么有人知道如何从另一个表中检索连接值而不是触发删除的表吗?谢谢
【问题讨论】:
-
您的理解似乎不正确。 AFTER 触发器“在主题表的实际更新导致的更改应用于数据库之后”触发 - 来自the manual 的引用。注意“数据库”与“表”。这显然包括“由主题表的实际更新引起的”级联操作。
-
mustaccio,正如我所说,我还尝试了 BEFORE 触发器,结果相同。如果我理解正确,您建议尝试“在更新或删除之前不要级联”。我会尝试。我想我也尝试过,但在添加触发器时遇到了问题,其中包含我不太理解的消息。我会及时通知你我的结果。感谢您的评论
-
似乎 NO CASCADE BEFORE 选项有效。现在我有另一个问题:我在我的程序中使用了一个聪明的持久性框架,它确定地址对象也需要被删除,所以如果我想使用 TRIGGER 解决方案,我必须用它来对抗框架缓存和对象映射之类的,这听起来像是一场你只能输的战斗。
标签: triggers db2 foreign-keys