UPDATE tab1 SET (a, b) = (a + 1, b + 1);
CREATE TRIGGER trig1 UPDATE OF a ON tab1-- Valid AFTER (UPDATE tab2 SET e = e + 1); CREATE TRIGGER trig2 UPDATE OF e ON tab2-- Invalid AFTER (UPDATE tab1 SET b = b + 1);
现在考虑以下 SQL 语句,当执行最终的 UPDATE 语句时,列 a 被更新且触发器 trig1 被激活。
CREATE TABLE temp1 (a INT, b INT, e INT); INSERT INTO temp1 VALUES (10, 20, 30); CREATE PROCEDURE proc(val iINT) RETURNING INT,INT; RETURN val+10, val+20; END PROCEDURE; CREATE TRIGGER trig1 UPDATE OF a ON temp1 FOR EACH ROW (EXECUTE PROCEDURE proc(50) INTO a, e); CREATE TRIGGER trig2 UPDATE OF e ON temp1 FOR EACH ROW (EXECUTE PROCEDURE proc(100) INTO a, e); UPDATE temp1 SET (a,b) = (40,50);
该级联触发器示例有几个问题。首先,更新列 a 是否会再次激活触发器 trig1 ?答案是否定的。因为触发器已被激活,它没有被再次激活。如果触发操作是 EXECUTE PROCEDURE INTO 或 EXECUTE FUNCTION INTO 语句,只有那些从更新的列到之后(在触发器级联中)在该表中互斥的列上定义的触发器才被激活。其它触发器被忽略。
该示例产生的另一个问题是触发器 trig2 是否被激活。答案是肯定的。触发器 trig2 在列 e 上定义。直到现在,表 temp1 中的列 e 尚未被修改。触发器 trig2 被激活。
该示例产生的最后一个问题是执行 trig2 中您的触发操作后触发器 trig1 和 trig2 是否被激活。答案是否定的。两个触发器都不会被激活。在此之前列 a 和 e 已被更新一次,触发器 trig1 和 trig2 已被执行一次。数据库服务器忽略这些触发器且不激活它们。关于级联触发器的更多信息,请参阅级联触发器。
正如前面提到的,视图上的 INSTEAD OF 触发器在其它触发器操作中不能包含 EXECUTE PROCEDURE INTO 语句。而且,如果两个视图分别具有带有已定义的操作(在其它视图上执行插入操作)的 INSERT INSTEAD OF 触发器的话,会产生错误。