pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。
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 触发器。对于这类情形,规则和视图更为合适。
参见第 33 章以了解有关触发器的更多信息。
name要赋予新触发器的名称。它必须不同于同一表上任何其他触发器的名称。
BEFOREAFTER决定该函数是在事件之前还是之后被调用。
eventINSERT、UPDATE或DELETE之一;它指定将引发该触发器的事件。可以使用OR指定多个事件。
table该触发器所作用的表、视图或外部表的名称(可以是模式限定的)。
FOR EACH ROWFOR EACH STATEMENT这指定触发器过程是针对受触发事件影响的每一行引发一次,还是针对每条 SQL 语句只引发一次。如果两者都未指定,则默认为FOR EACH STATEMENT。
funcname一个由用户提供的函数,声明为不接受参数并返回 trigger 类型;当触发器被触发时,就会执行该函数。
arguments一个可选的、以逗号分隔的参数列表,在执行触发器时会传给该函数。 这些参数是字符串字面常量。这里也可以写简单名称和数字常量, 但它们都会被转换成字符串。请查阅该触发器函数所用实现语言的说明, 以了解如何在函数内部访问这些参数;这可能与普通函数参数不同。
要在表上创建触发器,用户必须拥有该表的TRIGGER权限。
使用DROP TRIGGER删除触发器。
在PostgreSQL 7.3 之前的版本中,必须将触发器函数声明为返回占位类型opaque,而不是trigger。为了支持加载旧转储文件,CREATE TRIGGER将接受声明为返回opaque的函数,但会发出通知,并将该函数声明的返回类型更改为trigger。
第 33.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 标准的扩展。
译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。