CREATE TRIGGER

定义一个新的触发器。数据库中不支持用户自定义触发器。

概要

CREATE TRIGGER <name> {BEFORE | AFTER} {<event> [OR ...]}
       ON <table> [ FOR [EACH] {ROW | STATEMENT} ]
       EXECUTE PROCEDURE <funcname> ( <arguments> )

描述

CREATE TRIGGER 用于创建新的触发器。该触发器将关联到指定的表,并在特定事件发生时执行指定的函数。若为同一事件定义了多个同类触发器,则按名称字母顺序触发。

重要提示:由于数据库系统的分布式特性,触发器对数据的操作受到严格限制。触发器中使用的函数必须是IMMUTABLE(不可变)的,这意味着它不能使用参数列表中未直接提供的信息。触发器中指定的函数也不能执行任何SQL语句,或以任何方式修改分布式数据库对象。鉴于触发器最常用于修改表结构(例如当某行更新时同步更新其他行),这些限制使得触发器在数据库中的实际应用价值极低。因此,数据库不支持用户自定义触发器。触发器无法应用于追加优化表。数据库支持仅捕获DDL事件的事件触发器,更多信息请参阅PostgreSQL事件触发器文档。

SELECT 不会修改任何行,因此无法创建 SELECT 触发器。此类情况下规则和视图更为合适。

参数

  • name
    • 新触发器的名称。该名称必须与同一张表中任何其他触发器的名称不同。
  • BEFORE AFTER
    • 确定函数是在事件发生之前还是之后被调用。如果触发器在事件发生之前触发,则可能跳过当前行的操作,或更改正在插入的行(仅限于INSERT和UPDATE操作)。如果触发器在事件发生之后触发,则所有更改(包括最后一次插入、更新或删除操作)都对触发器可见。
  • event
    • 指定将触发该触发器的事件(INSERTUPDATEDELETE)。可使用 OR 运算符指定多个事件。
  • table
    • 触发器所针对的表的名称(可选带模式限定)。
  • FOR EACH ROW
  • FOR EACH STATEMENT
    • 此选项指定触发器过程应在触发事件影响的每行数据上执行一次,还是仅在每个SQL语句执行时触发一次。若未指定,则默认采用FOR EACH STATEMENT模式。标记为FOR EACH ROW的触发器将在操作修改的每行数据上调用一次;而标记为FOR EACH STATEMENT的触发器仅在每次操作时执行一次,无论该操作修改多少行数据。
  • funcname
    • 用户提供的函数,声明为IMMUTABLE,不带参数,返回类型为trigger,在触发器触发时执行。该函数不得执行SQL语句或以任何方式修改数据库。
  • arguments
    • 当触发器运行时,可选地向函数提供以逗号分隔的参数列表。这些参数是字面字符串常量。此处也可写入简单名称和数值常量,但它们都将被转换为字符串。请查阅触发器函数实现语言的说明,了解如何在函数内部访问触发器参数;其方式可能与常规函数参数不同。

注意

要在表上创建触发器,用户必须对该表具有 TRIGGER 权限。

示例

声明触发器函数,然后声明触发器:

CREATE FUNCTION sendmail() RETURNS trigger AS 
'$GPHOME/lib/emailtrig.so' LANGUAGE C IMMUTABLE;

CREATE TRIGGER t_sendmail AFTER INSERT OR UPDATE OR DELETE 
ON mytable FOR EACH STATEMENT EXECUTE PROCEDURE sendmail();

兼容性

数据库中的CREATE TRIGGER语句实现了SQL标准的一个子集。目前缺少以下功能:

数据库对触发器调用的函数有严格限制,这使得触发器在数据库中的使用受到很大限制。因此,数据库不正式支持触发器。

SQL允许在更新特定列时触发触发器(例如AFTER UPDATE OF col1, col2)。

SQL允许您为“旧行”和“新行”或“旧表”和“新表”定义别名,以便在触发器动作的定义中使用(例如:CREATE TRIGGER ... ON tablename REFERENCING OLD ROW AS somename NEW ROW AS othername ...)。由于数据库允许使用任意数量的用户定义语言编写触发器程序,因此数据访问将以特定于该语言的方式进行处理。

YMatrix 仅允许在触发器动作中执行用户自定义函数。而标准允许执行多种其他SQL命令,例如将CREATE TABLE作为触发器动作。通过创建一个运行所需命令的用户自定义函数,可以轻松绕过此限制。

SQL规定多个触发器应按创建时间顺序触发。数据库采用名称排序方式,因其被认为更便捷。

SQL规定级联删除中的BEFORE DELETE触发器在级联DELETE操作完成后触发。数据库行为则要求BEFORE DELETE始终在删除操作前触发,即使是级联删除。此行为被认为更具一致性。 使用OR为单个触发器指定多个动作的能力,是数据库对SQL标准的扩展。

另见

CREATE FUNCTION, ALTER TRIGGER, DROP TRIGGER, CREATE RULE