跳到主要内容

CREATE TRIGGER

CREATE TRIGGER 语句用于创建一个新触发器。触发器是与表关联的数据库对象,当表发生指定事件时会激活触发器。

CREATE TRIGGER 语句的语法如下:

CREATE
[DEFINER = user]
TRIGGER trigger_name
trigger_time trigger_event
ON table_name FOR EACH ROW
[trigger_order]
trigger_body

trigger_time: { BEFORE | AFTER }

trigger_event: { INSERT | UPDATE | DELETE }

trigger_order: { FOLLOWS | PRECEDES } other_trigger_name

table_name 指定触发器所关联的表,该表必须是非 TEMPORARY 表,不能将触发器与临时表或视图关联。

触发器名称存在于 Schema 命名空间中,因而所有触发器在 Schema 中必须具有唯一的名称。不同 Schema 中的触发器可以具有相同的名称。

CREATE TRIGGER 要求与触发器关联的表具有 TRIGGER 权限。如果存在 DEFINER 子句,则所需的权限取决于 user 值。

trigger_time 指定触发器操作时间为 BEFOREAFTER,即指示触发器在要修改的每一行之前或之后激活。列值的基础检查在触发器激活之前进行,因此不能使用 BEFORE 触发器将不符合列类型的值转换为有效值。

trigger_event 表示激活触发器的操作类型,有效取值如下:

  • INSERT:每当在表中插入新行时,触发器就会激活。例如,通过 INSERTLOAD DATAREPLACE 语句插入数据。

  • UPDATE:只要行被修改(例如,通过 UPDATE 语句),触发器就会激活。

  • DELETE:每当从表中删除一行时(例如,通过 DELETEREPLACE 语句),触发器就会激活。DROP TABLETRUNCATE TABLE 语句不会激活此触发器。删除分区也不会激活 DELETE 触发器。

trigger_event 表示一种表操作类型,而不表示激活触发器的 SQL 语句的字面量类型。例如,INSERT 触发器不仅可以被 INSERT 语句激活,还可以被 LOAD DATA 语句激活,这两个语句都将行插入到表中。

可以为具有相同触发器事件和操作时间的表定义多个触发器。例如,一个表可以有两个 BEFORE UPDATE 触发器。默认情况下,具有相同触发事件和操作时间的触发器将按创建的先后顺序被激活。

trigger_order 子句可以通过关键字 FOLLOWSPRECEDES 指定具有相同触发器事件和操作时间的触发器顺序。FOLLOWS 关键字表示新触发器将在现有触发器之后激活。PRECEDES 关键字表示新触发器在现有触发器之前激活。

trigger_body 是触发器激活时要执行的语句。要执行多个语句,请使用 BEGIN ... END 复合语句。

在触发器主体中,可以使用别名 OLDNEW 来引用主表(与触发器关联的表)中的列。OLD.column_name 是指更新或删除当前行之前的列。NEW.column_name 是指要插入的新行或更新后的当前行的列。触发器不能使用 NEW.col_nameOLD.column_name 来引用生成列。

DEFINER 子句指定在触发器被激活并检查访问权限时所使用的账号。如果存在 DEFINER 子句,则 user 值应为指定为 'user_name'@'host_name' 的账号(例如 'admin'@'oblocalhost')或者由 CURRENT_USER() 函数获取的账户。如果省略 DEFINER 子句,则默认定义者是执行 CREATE TRIGGER 语句的用户,这等同于 DEFINER = CURRENT_USER

在检查以下触发器权限时会涉及 DEFINER 用户:

  • 使用 CREATE TRIGGER 语句创建触发器的用户必须具有 TRIGGER 权限。

  • 在触发激活时,将根据 DEFINER 用户检查权限。此用户必须具有以下权限:

    • 主表的 TRIGGER 权限。

    • 如果使用触发器主体中的 OLD.col_name 或者 NEW.col_name 引用表列,则要具有主表的 SELECT 权限。

    • 如果表列是由触发器主体中 SET NEW.col_name = value 来赋值的,则要具有主表的 UPDATE 权限。

    • 触发器执行的语句通常所需要的其他权限。

在触发器主体中,通过 CURRENT_USER() 函数返回用于在触发器激活时检查权限的账号属于 DEFINER 用户,而不是其操作导致触发器被激活的用户。

有关创建触发器的详细示例信息,请参见 触发器