pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。
CREATE TRIGGER — 定义一个新的触发器
CREATE TRIGGERname{ BEFORE | AFTER } {event[OR ...] } ONtableFOR EACH { ROW | STATEMENT } EXECUTE PROCEDUREfunc(arguments)
name给予新触发器的名称。
table现有表的名称。
eventINSERT、DELETE 或 UPDATE 之一。
func一个用户提供的函数。
CREATE触发器创建成功时返回此消息。
CREATE TRIGGER 将把一个新触发器登记到当前数据库中。该触发器将与关系 table 关联,并执行指定的函数 func。
可以指定触发器在操作试图作用于元组之前(BEFORE,即约束检查和 INSERT、UPDATE 或 DELETE 尝试之前)引发,或在操作尝试之后(AFTER,例如约束检查完毕且 INSERT、UPDATE 或 DELETE 已完成之后)引发。如果触发器在事件之前引发,它可以跳过对当前元组的操作,或者修改被插入的元组(仅适用于 INSERT 和 UPDATE 操作)。如果触发器在事件之后引发,那么所有更改(包括最后一次插入、更新或删除)对触发器都是“可见”的。
SELECT 不会修改任何行,因此无法创建 SELECT 触发器。对于这类情形,规则和视图更为合适。
更多信息参见 PostgreSQL 程序员指南 中关于 SPI 和触发器的章节。
在向表 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)作为被触发动作。通过创建一个执行这些命令的存储过程,这一限制不难绕过。
译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。