15.1.22 创建触发器语句
CREATE
[DEFINER = user]
TRIGGER [IF NOT EXISTS] trigger_name
trigger_time trigger_event
ON tbl_name FOR EACH ROW
[trigger_order]
trigger_body
trigger_time: { BEFORE | AFTER }
trigger_event: { INSERT | UPDATE | DELETE }
trigger_order: { FOLLOWS | PRECEDES } other_trigger_name
该语句创建一个新的触发器。触发器是与表相关联的命名数据库对象,在特定的事件发生时激活。触发器将与名称为 tbl_name
的表相关联,该表必须是永久表,不可以与临时表或视图相关联。
触发器名在模式命名空间中存在,意味着所有触发器在同一个模式下必须具有唯一的名称,而不同的模式下的触发器可以拥有相同的名称。
IF NOT EXISTS
防止在同一个模式下,如果已经存在同名触发器,则不发生错误。
本节描述了CREATE TRIGGER
语法。关于触发器语法和示例的详细讨论,请参见第27.3.1节,“触发器语法和示例”。
CREATE TRIGGER
需要与触发器关联的表的TRIGGER
特权。如果存在 DEFINER
子句,所需特权取决于 user
值,如第27.6节,“存储对象访问控制”中讨论。如果启用二进制日志记录,CREATE TRIGGER
可能需要SUPER
特权,如第27.7节,“存储程序二进制日志记录”中讨论。
DEFINER
子句确定在触发器激活时使用的安全上下文,后续部分将对其进行描述。
trigger_time
是触发器动作时间。它可以是 BEFORE
或 AFTER
,以指示触发器在每个要修改的行之前或之后激活。
基本列值检查在触发器激活前发生,因此不能使用 BEFORE
触发器将值转换为合法值。
trigger_event
指示激活触发器的操作类型。这些 trigger_event
值允许:
"trigger_event
" 不是表示激活触发器的 SQL 语句类型,而是表示表操作类型。例如,一个INSERT
触发器不仅激活于INSERT
语句,还激活于LOAD DATA
语句,因为这两个语句都将行插入到表中。
一个混淆的示例是 INSERT INTO ... ON DUPLICATE KEY UPDATE ...
语法:一个BEFORE INSERT
触发器激活于每一行,接着可能是AFTER INSERT
触发器或同时激活BEFORE UPDATE
和 AFTER UPDATE
触发器,取决于该行是否存在重复键。
级联外键操作不激活触发器。
可以为同一表定义多个触发器,它们具有相同的触发事件和动作时间。例如,可以有两个BEFORE UPDATE
触发器。默认情况下,具有相同触发事件和动作时间的触发器按照创建顺序激活。要影响触发器顺序,可以指定一个trigger_order
子句,该子句指示 FOLLOWS
或 PRECEDES
,并且指定一个具有相同触发事件和动作时间的现有触发器的名称。使用 FOLLOWS
,新触发器激活于现有触发器后;使用 PRECEDES
,新触发器激活于现有触发器前。
trigger_body
是触发器激活时执行的语句。要执行多个语句,使用BEGIN ... END
复合语句结构。这也使您可以使用存储程序中允许的同样语句。见第15.6.1节,“BEGIN ... END复合语句”。有些语句在触发器中不可用;见第27.8节,“存储程序限制”。
在触发器体内,您可以使用别名OLD
和NEW
来引用主体表(与触发器关联的表)的列。OLD.
引用一个将要更新或删除的行的列。col_name
NEW.
引用要插入或已更新的行的列。col_name
触发器不能使用NEW.
或者使用col_name
OLD.
来引用生成列。关于生成列的信息,见第15.1.20.8节,“CREATE TABLE 和生成列”。col_name
MySQL 在创建触发器时将存储sql_mode
系统变量的设置,并总是以这个设置强制执行触发器体不管触发器开始执行时当前服务器 SQL 模式是什么。
DEFINER take子句指定在触发器激活时间检查访问权限时使用的 MySQL 账户。如果存在DEFINER子句,user
值应该是指定的 MySQL 账户,如'user_name
'@'host_name
',CURRENT_USER
或CURRENT_USER()
。允许的user
值取决于您所持有的权限,详见第27.6节,“存储对象访问控制”。另外,请查看该节关于触发器安全的其他信息。
如果省略DEFINER子句,缺省定义者是执行CREATE TRIGGER
语句的用户。这等同于指定DEFINER = CURRENT_USER
。
MySQL 在检查触发器权限时考虑DEFINER用户如下:
-
在
CREATE TRIGGER
时,执行该语句的用户必须拥有TRIGGER
特权。 -
在触发器激活时间,权限将被检查对
DEFINER
用户。这个用户必须拥有这些特权:
在触发器体内,CURRENT_USER
函数返回用于检查权限的账户,这是触发器激活时的账户,而不是导致触发器被激活的用户。关于在触发器中的用户审核,请参见第8.2.23节,“基于SQL的账户活动审核”。
如果使用LOCK TABLES
锁定一个带有触发器的表,触发器内的表也将被锁定,详见LOCK TABLES 和 触发器。
关于触发器的使用,请参见第27.3.1节,“触发器语法和示例”。