pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。
CREATE TRIGGER — 定义一个新的触发器
CREATE TRIGGERname{ BEFORE | AFTER } {event[OR ...] } ONtableFOR EACH { ROW | STATEMENT } EXECUTE PROCEDUREfunc(arguments)
name要赋予新触发器的名称。它必须不同于同一表上任何其他触发器的名称。
eventINSERT、DELETE 或 UPDATE 之一。
table该触发器所作用的表的名称(可以是模式限定的)。
func一个用户提供的函数,声明为不接受参数并返回 trigger 类型。
arguments一个可选的逗号分隔的参数列表,在触发器执行时与标准触发器数据(例如新旧元组的内容)一起提供给该函数。这些参数是字面字符串常量。简单名称和数值常量也可以写在这里,但它们都会被转换为字符串。
CREATE TRIGGER触发器创建成功时返回此消息。
CREATE TRIGGER 将把一个新触发器登记到当前数据库中。该触发器将与关系 table 关联,并执行指定的函数 func。
可以指定触发器在操作试图作用于元组之前(BEFORE,即约束检查和 INSERT、UPDATE 或 DELETE 尝试之前)引发,或在操作尝试之后(AFTER,例如约束检查完毕且 INSERT、UPDATE 或 DELETE 已完成之后)引发。如果触发器在事件之前引发,它可以跳过对当前元组的操作,或者修改被插入的元组(仅适用于 INSERT 和 UPDATE 操作)。如果触发器在事件之后引发,那么所有更改(包括最后一次插入、更新或删除)对触发器都是“可见”的。
如果针对同一事件定义了多个同类触发器,它们将按名称的字母顺序引发。
SELECT 不会修改任何行,因此无法创建 SELECT 触发器。对于这类情形,规则和视图更为合适。
更多信息参见 PostgreSQL 程序员指南 中关于 SPI 和触发器的章节。
要在表上创建触发器,用户必须拥有该表的TRIGGER权限。
在PostgreSQL 7.3 之前的版本中,必须将触发器函数声明为返回占位类型opaque,而不是trigger。为了支持加载旧转储文件,CREATE TRIGGER将接受声明为返回opaque的函数,但会发出一条 NOTICE,并将该函数声明的返回类型更改为trigger。
截至当前版本,STATEMENT 触发器尚未实现。
关于如何移除触发器,参见 DROP TRIGGER 命令。
在向表 films 追加或更新行之前,检查指定的发行商代码是否存在于 distributors 表中:
CREATE TRIGGER if_dist_exists
BEFORE INSERT OR UPDATE ON films FOR EACH ROW
EXECUTE PROCEDURE check_primary_key ('did', 'distributors', 'did');
在取消一个发行商或更新其代码之前,移除对表 films 的所有引用:
CREATE TRIGGER if_film_exists
BEFORE DELETE OR UPDATE ON distributors FOR EACH ROW
EXECUTE PROCEDURE check_foreign_key (1, 'CASCADE', 'did', 'films', 'did');
第二个例子也可以使用外键约束来完成,如下所示:
CREATE TABLE distributors (
did DECIMAL(3),
name VARCHAR(40),
CONSTRAINT if_film_exists
FOREIGN KEY(did) REFERENCES films
ON UPDATE CASCADE ON DELETE CASCADE
);
SQL92 中没有 CREATE TRIGGER 语句。
PostgreSQL 中的 CREATE TRIGGER 语句实现了 SQL99 标准的一个子集。缺少以下功能:
SQL99 允许触发器在对特定列的更新时引发(例如 AFTER UPDATE OF col1, col2)。
SQL99 允许为“旧”行或表和“新”行或表定义别名,供被触发动作的定义使用(例如 CREATE TRIGGER ... ON tablename REFERENCING OLD ROW AS somename NEW ROW AS othername ...)。由于 PostgreSQL 允许用任意多种用户自定义语言编写触发器过程,对数据的访问以各语言特定的方式处理。
PostgreSQL 只有行级触发器,没有语句级触发器。
PostgreSQL 只允许被触发动作执行一个存储过程。SQL99 允许执行若干其他 SQL 命令(例如 CREATE TABLE)作为被触发动作。通过创建一个执行这些命令的存储过程,这一限制不难绕过。
SQL99 规定多个触发器应按创建时间的先后顺序引发。 PostgreSQL 使用名称顺序,这被判定为使用起来更方便。
译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。