• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • 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
    

    该语句创建一个新的触发器。触发器是与表关联的命名数据库对象,并在表发生特定事件时激活。触发器与名为的表相关联,该表tbl_name必须引用一个永久表。您不能将触发器与TEMPORARY表或视图关联。

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

    本节介绍CREATE TRIGGER语法。有关更多讨论,请参见“触发器语法和示例”。

    CREATE TRIGGER需要TRIGGER与触发器关联的表的特权。如果DEFINER存在该子句,则所需的特权取决于该user值,如“存储的对象访问控制”中所述。如果启用了二进制日志记录,则CREATE TRIGGER可能需要SUPER特权,如“存储的程序二进制日志记录”中所述。

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

    trigger_time是触发动作时间。可以是BEFOREAFTER表示触发器在要修改的每一行之前或之后激活。

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

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

    • INSERT:每当在表中插入新行时(例如,通过,和语句)INSERT,触发器就会激活。LOAD DATAREPLACE
    • UPDATE:只要修改一行(例如,通过UPDATE语句),触发器就会激活。
    • DELETE:只要从表中删除一行(例如,通过DELETEREPLACE语句),触发器就会激活。DROP TABLETRUNCATE TABLE表上的语句不会激活此触发器,因为它们未使用DELETE。删除分区也不会激活DELETE触发器。

    trigger_event不代表文本类型激活触发器的这么多,因为它代表了一种类型的表操作的SQL语句。例如,INSERT触发器不仅会激活INSERT语句,还会激活LOAD DATA语句,因为这两个语句都会在表中插入行。

    INSERT INTO ... ON DUPLICATE KEY UPDATE ...语法的一个可能令人困惑的示例是:BEFORE INSERT每个行都会AFTER INSERT触发一个触发器,然后触发一个触发器,或者同时触发BEFORE UPDATEAFTER UPDATE触发器,这取决于该行是否有重复的键。

    注意

    级联的外键操作不会激活触发器。

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

    trigger_body是触发器激活时要执行的语句。要执行多个语句,请使用BEGIN ... END复合语句构造。这也使您能够使用存储例程中允许的相同语句。请参见“ BEGIN ... END复合语句”。触发器中不允许某些语句;请参见“对存储程序的限制”。

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

    触发器不能使用或用于引用生成的列。有关生成的列的信息,请参见“创建表和生成的列”。NEW.col_nameOLD.col_name

    MySQL会sql_mode在创建触发器时存储有效的系统变量设置,并且始终在该设置生效的情况下执行触发器主体,而不管触发器开始执行时当前的服务器SQL模式如何

    DEFINER子句指定在触发器激活时检查访问权限时要使用的MySQL帐户。如果DEFINER子句,该user值应被指定为一个MySQL帐户,或。允许的值取决于您拥有的特权,如“存储的对象访问控制”中所述。另请参阅该部分以获取有关触发器安全性的其他信息。'user_name'@'host_name'CURRENT_USERCURRENT_USER()user

    如果DEFINER省略该子句,则默认定义器是执行该CREATE TRIGGER语句的用户。这与DEFINER = CURRENT_USER显式指定相同。

    DEFINER当检查触发特权时, MySQL将用户考虑在内,如下所示:

    • CREATE TRIGGER时间上,发出该语句的用户必须具有TRIGGER特权。
    • 在触发激活时,将针对DEFINER用户检查特权。该用户必须具有以下特权:

      • TRIGGER主题表的特权。
      • SELECT如果表列的引用发生使用主题表特权或在触发器主体。OLD.col_nameNEW.col_name
      • UPDATE如果表列是触发器主体中的分配目标,则主题表的特权。SET NEW.col_name= value
      • 触发器执行的语句通常需要任何其他特权。

    在触发器主体内,该CURRENT_USER函数返回用于在触发器激活时检查特权的帐户。这是DEFINER用户,而不是其操作导致触发器被激活的用户。有关触发器内用户审核的信息,请参见“基于SQL的帐户活动审核”。

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

    有关触发器使用的更多讨论,请参见“触发器语法和示例”。