mysql触发器是依附于表的数据库对象,当表上发生INSERT、UPDATE、DELETE等指定事件时,触发器会自动执行定义好的逻辑,无需手动调用,常用于数据校验、操作日志记录、关联数据同步等场景。

mysql触发器的核心概念
在使用触发器前,需要先了解几个核心要素:
- 触发事件:触发触发器的操作类型,支持INSERT、UPDATE、DELETE三种。
- 触发时机:分为BEFORE和AFTER两种,BEFORE表示在触发事件执行前运行触发器逻辑,AFTER表示在触发事件执行后运行触发器逻辑。
- 触发对象:触发器依附的表,每个触发器只能关联一张表。
mysql触发器的创建语法
创建mysql触发器的标准语法如下:
-- 修改语句结束符,避免和触发器内的分号冲突
DELIMITER //
CREATE TRIGGER 触发器名称
触发时机 触发事件 ON 表名
FOR EACH ROW
BEGIN
-- 触发器逻辑代码,支持多条sql语句
END //
-- 恢复默认语句结束符
DELIMITER ;
语法说明:
- 触发器名称需要保证全局唯一,建议命名格式为
表名_触发时机_触发事件_trigger,方便识别。 FOR EACH ROW表示触发器是行级触发,每操作一行数据就会执行一次触发器逻辑。- 如果触发器逻辑只有一条sql语句,可以省略
BEGIN和END。
mysql触发器使用实战示例
示例1:创建操作日志触发器
假设我们有一张用户表user和一张用户操作日志表user_log,需要在用户表发生新增、修改、删除操作时,自动记录操作日志。
首先创建两张表:
-- 用户表
CREATE TABLE user (
id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(50) NOT NULL,
age INT,
create_time DATETIME DEFAULT CURRENT_TIMESTAMP
);
-- 用户操作日志表
CREATE TABLE user_log (
id INT PRIMARY KEY AUTO_INCREMENT,
user_id INT,
operation_type VARCHAR(20),
operation_time DATETIME DEFAULT CURRENT_TIMESTAMP,
old_data TEXT,
new_data TEXT
);
创建新增用户时的AFTER INSERT触发器:
DELIMITER //
CREATE TRIGGER user_after_insert_trigger
AFTER INSERT ON user
FOR EACH ROW
BEGIN
INSERT INTO user_log (user_id, operation_type, new_data)
VALUES (NEW.id, 'INSERT', CONCAT('username:', NEW.username, ',age:', NEW.age));
END //
DELIMITER ;
创建修改用户时的AFTER UPDATE触发器:
DELIMITER //
CREATE TRIGGER user_after_update_trigger
AFTER UPDATE ON user
FOR EACH ROW
BEGIN
INSERT INTO user_log (user_id, operation_type, old_data, new_data)
VALUES (NEW.id, 'UPDATE',
CONCAT('username:', OLD.username, ',age:', OLD.age),
CONCAT('username:', NEW.username, ',age:', NEW.age)
);
END //
DELIMITER ;
创建删除用户时的AFTER DELETE触发器:
DELIMITER //
CREATE TRIGGER user_after_delete_trigger
AFTER DELETE ON user
FOR EACH ROW
BEGIN
INSERT INTO user_log (user_id, operation_type, old_data)
VALUES (OLD.id, 'DELETE', CONCAT('username:', OLD.username, ',age:', OLD.age));
END //
DELIMITER ;
测试触发器的效果,执行新增用户操作:
INSERT INTO user (username, age) VALUES ('张三', 25);
此时查询user_log表,会发现自动生成了一条INSERT类型的操作记录。执行修改用户操作:
UPDATE user SET age = 26 WHERE username = '张三';
同样会在user_log表中生成对应的UPDATE操作记录,包含修改前和修改后的数据。
示例2:创建数据校验触发器
如果需要在用户新增数据时校验年龄不能为负数,可以创建BEFORE INSERT触发器:
DELIMITER //
CREATE TRIGGER user_before_insert_check_trigger
BEFORE INSERT ON user
FOR EACH ROW
BEGIN
-- 如果年龄小于0,抛出错误
IF NEW.age < 0 THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '用户年龄不能为负数';
END IF;
END //
DELIMITER ;
此时执行年龄为负数的新增操作:
INSERT INTO user (username, age) VALUES ('李四', -5);
会直接返回错误提示,数据不会插入到用户表中,实现了数据校验的效果。
mysql触发器的查看和删除
查看当前数据库所有触发器的语法:
SHOW TRIGGERS;
查看指定触发器的定义:
SHOW CREATE TRIGGER 触发器名称;
删除触发器的语法:
DROP TRIGGER 触发器名称;
mysql触发器使用注意事项
- 触发器不能返回结果集,只能执行数据操作相关的逻辑。
- 同一个表同一个触发时机同一个触发事件只能创建一个触发器,比如user表已经存在AFTER INSERT触发器,不能再创建同类型的触发器。
- 触发器中不能使用动态sql语句,也不能调用存储过程。
- 触发器逻辑执行失败会导致触发它的操作也失败,比如BEFORE触发器执行出错,对应的INSERT、UPDATE、DELETE操作会回滚。
- 过度使用触发器会增加数据库的性能开销,且逻辑分散在触发器中不利于维护,建议只在必要的场景使用。