PingKai Logo下载

CREATE TRIGGER

CREATE TRIGGER 语句用于在普通表上创建行级触发器。 当指定的 INSERTUPDATEDELETE 事件发生时, 触发器会自动执行定义的 SQL 语句或 BEGIN ... END 复合语句。

语法图

CreateTriggerStmt ::=
    'CREATE' TriggerDefiner 'TRIGGER' IfNotExists TriggerName
    TriggerTiming TriggerEvent 'ON' TableName
    'FOR' 'EACH' 'ROW' TriggerOrder TriggerBody

TriggerDefiner ::=
    ( 'DEFINER' '=' Username )?

IfNotExists ::=
    ( 'IF' 'NOT' 'EXISTS' )?

TriggerName ::= TableName

TriggerTiming ::=
    'BEFORE'
|   'AFTER'

TriggerEvent ::=
    'INSERT'
|   'UPDATE'
|   'DELETE'

TriggerOrder ::=
    ( ( 'FOLLOWS' | 'PRECEDES' ) Identifier )?

TriggerBody ::=
    A single SQL statement or a 'BEGIN' ... 'END' compound statement

语法说明

CREATE [DEFINER = user] TRIGGER [IF NOT EXISTS] trigger_name
    {BEFORE | AFTER} {INSERT | UPDATE | DELETE}
    ON tbl_name FOR EACH ROW
    [FOLLOWS other_trigger_name | PRECEDES other_trigger_name]
    trigger_body

参数说明

参数说明
DEFINER指定触发器的定义者。未指定时,TiDB 使用当前用户作为定义者。
IF NOT EXISTS如果同名触发器已经存在,则返回 Note 而不是报错。
trigger_name触发器名称。触发器名称与目标表必须位于同一个数据库中。
BEFORE | AFTER指定触发器在目标事件之前或之后执行。
INSERT | UPDATE | DELETE指定触发器绑定的事件类型。
tbl_name触发器绑定的目标表。TiDB 仅支持在普通表上创建触发器。
FOLLOWS / PRECEDES当同一张表上存在多个相同时机、相同事件的触发器时,用于显式指定执行顺序。
trigger_body触发器执行体,可以是一条 SQL 语句,也可以是 BEGIN ... END 复合语句。

使用说明

  • 创建、删除和查看触发器时,需要拥有目标表上的 TRIGGER 权限。
  • 触发器只能定义在普通表上,不支持视图、序列、临时表或系统库中的表。
  • OLD 伪记录仅可用于 UPDATEDELETE 触发器;NEW 伪记录仅可用于 INSERTUPDATE 触发器。
  • NEW 伪记录只能在 BEFORE INSERTBEFORE UPDATE 触发器中修改。
  • 触发器体不能直接返回结果集。如果需要查询结果,请使用 SELECT ... INTO 将结果写入变量。
  • 如果没有显式指定 FOLLOWSPRECEDES,多个同类触发器默认按创建顺序执行。

示例

BEFORE INSERT 触发器中修改待写入的行

CREATE TABLE trig_demo (
    id INT PRIMARY KEY,
    v INT,
    note VARCHAR(20)
);

CREATE TRIGGER trg_fill
BEFORE INSERT ON trig_demo
FOR EACH ROW
SET NEW.note = CONCAT('v=', NEW.v);

INSERT INTO trig_demo(id, v) VALUES (1, 10), (2, 20);
SELECT * FROM trig_demo ORDER BY id;
+----+------+------+
| id | v    | note |
+----+------+------+
|  1 |   10 | v=10 |
|  2 |   20 | v=20 |
+----+------+------+

AFTER INSERT 触发器中写入审计表

CREATE TABLE trig_log (
    id INT PRIMARY KEY AUTO_INCREMENT,
    msg VARCHAR(50)
);

CREATE TRIGGER trg_log
AFTER INSERT ON trig_demo
FOR EACH ROW
INSERT INTO trig_log(msg)
VALUES (CONCAT('insert:', NEW.id, ':', NEW.note));

INSERT INTO trig_demo(id, v) VALUES (3, 30);
SELECT * FROM trig_log ORDER BY id;
+----+---------------+
| id | msg           |
+----+---------------+
|  1 | insert:3:v=30 |
+----+---------------+

通过 FOLLOWSPRECEDES 指定执行顺序

CREATE TABLE trig_order (
    id INT PRIMARY KEY,
    v INT
);

CREATE TABLE trig_order_log (
    id INT PRIMARY KEY AUTO_INCREMENT,
    msg VARCHAR(10)
);

CREATE TRIGGER trg_a
BEFORE INSERT ON trig_order
FOR EACH ROW
INSERT INTO trig_order_log(msg) VALUES ('a');

CREATE TRIGGER trg_b
BEFORE INSERT ON trig_order
FOR EACH ROW
FOLLOWS trg_a
INSERT INTO trig_order_log(msg) VALUES ('b');

CREATE TRIGGER trg_c
BEFORE INSERT ON trig_order
FOR EACH ROW
PRECEDES trg_b
INSERT INTO trig_order_log(msg) VALUES ('c');

INSERT INTO trig_order VALUES (1, 1);
SELECT GROUP_CONCAT(msg ORDER BY id SEPARATOR '') AS order_seen FROM trig_order_log;
+------------+
| order_seen |
+------------+
| acb        |
+------------+

查看和删除触发器

创建完成后,可以使用以下语句查看或删除触发器:

SHOW TRIGGERS LIKE 'trg_%';
SHOW CREATE TRIGGER trg_fill;
DROP TRIGGER trg_fill;

MySQL 兼容性

TiDB 支持 CREATE TRIGGERDROP TRIGGERSHOW TRIGGERSSHOW CREATE TRIGGER。 如发现任何兼容性差异,请尝试 TiDB 支持资源

另请参阅