CREATE TRIGGER
CREATE TRIGGER — 定义一个新触发器
大纲
CREATE TRIGGERname{ BEFORE | AFTER } {event[ OR ... ] } ONtable[ FOR [ EACH ] { ROW | STATEMENT } ] EXECUTE PROCEDUREfuncname(arguments)
描述
CREATE TRIGGER创建一个新触发器。触发器会关联到指定的表,并在发生某些事件时执行指定的函数funcname。
可以指定触发器在尝试对某一行执行该操作之前引发(即在检查约束以及尝试执行INSERT、UPDATE或DELETE之前);也可以在该操作完成之后引发(即在检查约束以及完成
INSERT、UPDATE或
DELETE之后)。如果触发器在事件之前引发,则它可以跳过对当前行的操作,或者修改待插入的行(仅适用于INSERT和UPDATE操作)。如果触发器在事件之后引发,则所有更改(包括最后一次插入、更新或删除)对该触发器都是“可见”的。
被标记为FOR EACH ROW的触发器会针对该操作修改的每一行调用一次。例如,一个影响 10 行的DELETE会导致目标关系上的
ON DELETE触发器分别被调用 10 次,即每个被删除的行调用一次。相比之下,被标记为FOR EACH STATEMENT的触发器对于任意给定操作只执行一次,不管该操作修改了多少行(特别是,修改零行的操作仍会导致所有适用的
FOR EACH STATEMENT触发器执行)。
如果针对同一事件定义了多个同类触发器,它们将按名称的字母顺序引发。
SELECT 不会修改任何行,因此无法创建
SELECT 触发器。对于这类情形,规则和视图更为合适。
参见第 35 章以了解有关触发器的更多信息。
参数
name要赋予新触发器的名称。它必须不同于同一表上任何其他触发器的名称。
BEFOREAFTER决定该函数是在事件之前还是之后被调用。
eventINSERT、UPDATE或DELETE之一;它指定将引发该触发器的事件。可以使用OR指定多个事件。table该触发器所作用的表的名称(可以是模式限定的)。
FOR EACH ROWFOR EACH STATEMENT这指定触发器过程是针对受触发事件影响的每一行引发一次,还是针对每条 SQL 语句只引发一次。如果两者都未指定,则默认为
FOR EACH STATEMENT。funcname一个由用户提供的函数,声明为不接受参数并返回
trigger类型;当触发器被触发时,就会执行该函数。arguments一个可选的、以逗号分隔的参数列表,在执行触发器时会传给该函数。这些参数是字符串字面常量。这里也可以写简单名称和数字常量,但它们都会被转换成字符串。请查阅该触发器函数所用实现语言的说明,以了解如何在函数内部访问这些参数;这可能与普通函数参数不同。
注解
要在表上创建触发器,用户必须拥有该表的TRIGGER权限。用户还必须拥有触发器函数的EXECUTE权限。
在PostgreSQL 7.3 之前的版本中,必须将触发器函数声明为返回占位类型opaque,而不是trigger。为了支持加载旧转储文件,CREATE TRIGGER将接受声明为返回opaque的函数,但会发出通知,并将该函数声明的返回类型更改为trigger。
使用DROP TRIGGER删除触发器。
示例
第 35.4 节包含一个完整示例。
兼容性
PostgreSQL 中的 CREATE TRIGGER
语句实现了 SQL 标准的一个子集。当前仍缺少以下功能:
SQL 允许触发器在特定列被更新时引发(例如
AFTER UPDATE OF col1, col2)。SQL 允许为在触发动作定义中使用的“旧”行或“新”行定义别名(例如
CREATE TRIGGER ... ON tablename REFERENCING OLD ROW AS somename NEW ROW AS othername ...)。由于 PostgreSQL 允许用任意多种用户定义的语言编写触发器过程,对数据的访问是以语言相关的方式处理的。PostgreSQL 只允许通过执行用户定义函数来完成触发动作。标准则允许把许多其他 SQL 命令(例如
CREATE TABLE)作为触发动作执行。通过创建一个执行所需命令的用户定义函数,这一限制并不难绕过。
SQL 规定多个触发器应按创建时间顺序引发。PostgreSQL 则按名称顺序引发,这被认为更方便。
SQL 规定,级联删除上的 BEFORE DELETE 触发器应在级联
DELETE 完成之后引发。PostgreSQL 的行为则是
BEFORE DELETE 总会在删除动作之前引发,即使是级联删除也一样。这被认为更一致。此外,当 BEFORE 触发器修改随后将被引用动作修改的行时,行为也不可预测。这可能导致约束违反,或者使存储的数据不符合引用约束。
使用 OR 为单个触发器指定多个动作的能力,是
PostgreSQL 对 SQL 标准的扩展。