13.1.20 CREATE TRIGGER 语句
CREATE
[DEFINER = user]
TRIGGER 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
该语句创建一个新的触发器。触发器是与 table 相关联的命名数据库对象,并在 table 发生特定事件时激活。触发器与名为* tbl_name
*的 table 相关联,该 table 必须引用一个永久 table。您不能将触发器与TEMPORARY
table 或视图相关联。
触发器名称存在于模式名称空间中,这意味着所有触发器在模式内必须具有唯一的名称。不同架构中的触发器可以具有相同的名称。
本节介绍CREATE TRIGGER语法。有关其他讨论,请参见第 23.3.1 节“触发器语法和示例”。
CREATE TRIGGER要求具有与触发器关联的 table 的TRIGGER特权。如果存在DEFINER
子句,则所需的特权取决于* user
*值,如第 23.6 节“存储的对象访问控制”中所述。如果启用了二进制日志记录,则CREATE TRIGGER可能需要SUPER特权,如第 23.7 节“存储的程序二进制日志”中所述。
DEFINER
子句确定在触发器激活时检查访问权限时要使用的安全上下文,如本节后面所述。
trigger_time
*是触发动作时间。可以是BEFORE
或AFTER
来指示触发器在要修改的每一行之前或之后激活。
基本的列值检查在激活触发器之前进行,因此您不能使用BEFORE
触发器将不适用于该列类型的值转换为有效值。
trigger_event
table 示激活触发器的操作类型。这些trigger_event
*值是允许的:
-
INSERT:每当在 table 中插入新行时(例如,通过INSERT,LOAD DATA和REPLACE语句),触发器就会激活。
-
DELETE:每当从 table 中删除一行时(例如,通过DELETE和REPLACE语句),触发器就会激活。table 上的DROP TABLE和TRUNCATE TABLE语句不激活该触发器,因为它们不使用DELETE。删除分区也不会激活DELETE触发器。
trigger_event
*并不 table 示激活触发器的 SQL 语句的 Literals 类型,而是 table 示 table 操作的类型。例如,INSERT触发器不仅为INSERT语句激活,而且为LOAD DATA语句激活,因为这两个语句都将行插入 table 中。
一个可能令人困惑的例子是INSERT INTO ... ON DUPLICATE KEY UPDATE ...
语法:每行都会激活BEFORE INSERT
触发器,然后是AFTER INSERT
触发器或BEFORE UPDATE
和AFTER UPDATE
触发器,这取决于该行是否有重复的键。
Note
级联的外键操作不会激活触发器。
可以为给定的 table 定义具有相同触发事件和动作时间的多个触发。例如,一个 table 可以有两个BEFORE UPDATE
触发器。默认情况下,具有相同触发事件和动作时间的触发器将按照其创建 Sequences 进行激活。要影响触发器的 Sequences,请指定* trigger_order
*子句以指示FOLLOWS
或PRECEDES
以及现有触发器的名称,该触发器也具有相同的触发器事件和动作时间。使用FOLLOWS
,新触发器将在现有触发器之后激活。使用PRECEDES
,新触发器将在现有触发器之前激活。
trigger_body
*是触发触发器时要执行的语句。要执行多个语句,请使用开始...结束复合语句构造。这也使您能够使用存储例程中允许的相同语句。参见第 13.6.1 节“ BEGIN ... END 复合语句”。触发器中不允许某些语句;参见第 23.8 节“对存储程序的限制”。
在触发器主体内,您可以使用别名OLD
和NEW
来引用主题 table(与触发器关联的 table)中的列。 OLD.col_name
指的是更新或删除现有行的列。 NEW.col_name
是指要插入的新行或更新后的现有行的列。
触发器不能使用NEW.col_name
或OLD.col_name
来引用生成的列。有关生成的列的信息,请参见第 13.1.18.7 节“创建 table 和生成的列”。
MySQL 会在创建触发器时存储有效的sql_mode系统变量设置,并始终在有效的情况下执行触发器主体,而与触发器开始执行时当前的服务器 SQL 模式无关。
DEFINER
子句指定在触发器激活时检查访问权限时要使用的 MySQL 帐户。如果存在DEFINER
子句,则* user
值应为指定为'user_name'@'host_name'
,CURRENT_USER或CURRENT_USER()的 MySQL 帐户。允许的 user
*值取决于您所拥有的特权,如第 23.6 节“存储的对象访问控制”中所述。另请参阅该部分以获取有关触发器安全性的其他信息。
如果省略DEFINER
子句,则默认定义器是执行CREATE TRIGGER语句的用户。这与显式指定DEFINER = CURRENT_USER
相同。
当检查触发特权时,MySQL 将DEFINER
用户考虑在内:
-
在CREATE TRIGGER时间,发出该语句的用户必须具有TRIGGER特权。
-
在触发器激活时,将针对
DEFINER
用户检查特权。该用户必须具有以下特权: -
主题 table 的TRIGGER特权。
在触发器主体中,CURRENT_USER函数返回用于在触发器激活时检查特权的帐户。这是DEFINER
用户,而不是其操作导致触发器被激活的用户。有关触发器内用户审核的信息,请参见第 6.2.18 节“基于 SQL 的帐户活动审核”。
如果您使用LOCK TABLES锁定具有触发器的 table,则该触发器中使用的 table 也会被锁定,如锁定 table 和触发器中所述。
有关触发器使用的其他讨论,请参见第 23.3.1 节“触发器语法和示例”。