Documentation Home
MySQL 8.3 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 40.8Mb
PDF (A4) - 40.9Mb
Man Pages (TGZ) - 294.0Kb
Man Pages (Zip) - 409.0Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb
Excerpts from this Manual

MySQL 8.3 Reference Manual  /  ...  /  CREATE TRIGGER Statement

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 的表关联,该表必须是一个永久表。您不能将触发器与 TEMPORARY 表或视图关联。

触发器名称存在于模式命名空间中,这意味着所有触发器在同一个模式中必须具有唯一的名称。不同模式中的触发器可以具有相同的名称。

IF NOT EXISTS 防止在同一个模式中已经存在具有相同名称的触发器时发生错误。

本节描述 CREATE TRIGGER 语法。有关更多讨论,请参阅 第 27.3.1 节,“触发器语法和示例”

CREATE TRIGGER 需要对关联的表具有 TRIGGER 权限。如果存在 DEFINER 子句,则权限取决于 user 值,如 第 27.6 节,“存储对象访问控制” 中所讨论的那样。如果启用了二进制日志记录,CREATE TRIGGER 可能需要 SUPER 权限,如 第 27.7 节,“存储程序二进制日志记录” 中所讨论的那样。

DEFINER 子句确定在触发器激活时检查访问权限的安全上下文,如本节后面所述。

trigger_time 是触发器激活时间。它可以是 BEFOREAFTER,以指示触发器在每行修改之前或之后激活。

基本列值检查在触发器激活之前进行,因此您不能使用 BEFORE 触发器将不适合列类型的值转换为有效值。

trigger_event 指示激活触发器的操作类型。这些 trigger_event 值是允许的:

触发器事件 trigger_event 不是指文字上的 SQL 语句类型,而是指表操作类型。例如,INSERT 触发器不仅激活于 INSERT 语句,还激活于 LOAD DATA 语句,因为两者都将行插入到表中.

一个可能混淆的示例是 INSERT INTO ... ON DUPLICATE KEY UPDATE ... 语法:BEFORE INSERT 触发器将激活每一行,然后是 AFTER INSERT 触发器或 BEFORE UPDATEAFTER UPDATE 触发器,取决于是否存在重复键.

Note

级联外键操作不激活触发器.

可以为给定表定义多个触发器,这些触发器具有相同的触发事件和操作时间。例如,可以为一个表定义两个 BEFORE UPDATE 触发器。默认情况下,具有相同触发事件和操作时间的触发器将按照创建顺序激活。要影响触发器顺序,请指定一个 trigger_order 子句,指示 FOLLOWSPRECEDES 和具有相同触发事件和操作时间的现有触发器的名称。使用 FOLLOWS,新的触发器将在现有触发器之后激活。使用 PRECEDES,新的触发器将在现有触发器之前激活。

trigger_body 是触发器激活时要执行的语句。要执行多个语句,请使用 BEGIN ... END 复合语句构造。这也使您可以使用存储过程中允许的相同语句。请参阅 第 15.6.1 节,“BEGIN ... END 复合语句”。一些语句不允许在触发器中使用;请参阅 第 27.8 节,“存储程序限制”

在触发器体中,您可以使用别名 OLDNEW 引用关联表(与触发器关联的表)的列。OLD.col_name 引用更新或删除前的现有行的列。NEW.col_name 引用要插入的新行或更新后的现有行的列。

触发器不能使用 NEW.col_name 或使用 OLD.col_name 引用生成的列。有关生成的列的信息,请参阅 第 15.1.20.8 节,“CREATE TABLE 和生成的列”

MySQL 将触发器创建时的 sql_mode 系统变量设置存储在触发器中,并总是使用该设置来执行触发器体,无论当前服务器 SQL 模式何时开始执行触发器

DEFINER 子句指定了在触发器激活时检查访问权限的 MySQL 帐户。如果存在 DEFINER 子句,则 user 值应为指定的 MySQL 帐户,格式为 'user_name'@'host_name'CURRENT_USERCURRENT_USER()。允许的 user 值取决于您拥有的权限,如 第 27.6 节,“存储对象访问控制” 中所讨论的那样。还请参阅该节以获取触发器安全的更多信息。

如果省略 DEFINER 子句,则默认定义者是执行 CREATE TRIGGER 语句的用户。这相当于明确指定 DEFINER = CURRENT_USER

MySQL 在检查触发器权限时考虑 DEFINER 用户,如下所示:

  • CREATE TRIGGER 时,执行语句的用户必须拥有 TRIGGER 权限。

  • 在触发器激活时,权限将检查到 DEFINER 用户。这用户必须拥有以下权限:

    • 对主题表的 TRIGGER 权限。

    • 如果在触发器体中使用 OLD.col_nameNEW.col_name 引用表列,则对主题表的 SELECT 权限。

    • 如果在触发器体中将表列作为 SET NEW.col_name = value 赋值的目标,则对主题表的 UPDATE 权限。

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

在触发器体中,CURRENT_USER 函数返回在触发器激活时用于检查权限的账户。这是 DEFINER 用户,而不是触发器激活的用户的账户。有关触发器中的用户审核信息,请参阅 第 8.2.23 节,“基于 SQL 的账户活动审核”

如果您使用 LOCK TABLES 锁定具有触发器的表,则触发器中使用的表也将被锁定,如 LOCK TABLES 和触发器 中所述。

有关触发器使用的更多讨论,请参阅 第 27.3.1 节,“触发器语法和示例”