IBM DB2 on Cloud,版本 11.5.9.0
尝试在表上创建触发器(为了简化,对象名称是虚构的):
CREATE OR REPLACE TRIGGER MY_TRIGGER
AFTER UPDATE OR INSERT ON MY_TABLE
REFERENCING NEW TABLE AS NEW_STUFF
FOR EACH STATEMENT
BEGIN ATOMIC
DELETE FROM TABLE_A WHERE P_N IN (SELECT DISTINCT P_N FROM NEW_STUFF);
INSERT INTO TABLE_A SELECT * FROM VIEW_B WHERE P_N IN (SELECT DISTINCT P_N FROM NEW_STUFF);
END;
视图 VIEW_B 在其定义中确实有 TABLE_A 作为引用。
我收到此错误:
SQL Error [42601]: An unexpected token "OR INSERT" was found following "".
Expected tokens may include: ""..
SQLCODE=-104, SQLSTATE=42601
如果我创建仅使用AFTER UPDATE ON MY_TABLE或仅使用AFTER INSERT ON MY_TABLE 的相同触发器,它会正常工作。当我同时指定AFTER UPDATE 或 INSERT时,它会失败。
如果我尝试BEGIN而不是BEGIN ATOMIC我会得到不同的错误:
SQL Error [42898]: The definition of trigger "MY_SCHEMA.MY_TRIGGER" includes an
invalid use of correlation name or transition table name "NEW_STUFF".
Reason code="4".. SQLCODE=-696, SQLSTATE=42898
我研究了文档和我能找到的几个例子。如果有人知道为什么 UPDATE 或 INSERT 的组合会导致它失败,我将不胜感激。
根据文档,如果指定了多个事件(并且您指定了两个,更新或插入),则触发的操作必须是已编译的语句(即不能是“Begin atomic”)。这就是您在第一种情况下获得 SQL0104N 的原因。
接下来,对于第二种情况,当您有一个用于触发操作的编译语句时,那么
OLD TABLE name and NEW TABLE name are not allowed in a trigger if the trigger is defined using a compound SQL (compiled) statement.
(这就是您获得 SQL0696N 的原因代码 4 的原因)。考虑使用单独的触发器,而不是尝试将两者组合成单个触发器,或者选择符合限制的其他设计。