触发器是一种特殊的数据库对象,在特定事件(如INSERT
、UPDATE
或DELETE
)触发时自动执行定义好的操作。它可以帮助我们实现更高效的数据管理和业务规则的约束。
1. 简介
1.1 什么是触发器
触发器(Trigger)是由用户定义的一组 SQL 语句,在数据库表上进行某些特定操作时自动触发执行。
1.2 触发器的作用
- 数据一致性:在数据修改前后执行验证,确保数据的完整性和一致性。
- 自动化处理:简化业务逻辑,例如记录日志、更新关联表。
- 强制约束:在数据库层面实现复杂规则,避免业务逻辑遗漏。
1.3 触发器的特性
- 每个触发器绑定到一个表。
- 支持触发的事件:
INSERT
、UPDATE
、DELETE
。 - 支持触发时机:
BEFORE
(操作之前触发)和AFTER
(操作之后触发)。 - 不支持触发器内直接调用事务控制语句(如
COMMIT
或ROLLBACK
)。
2. 语法
2.1 创建触发器
sql
CREATE TRIGGER 触发器名
{BEFORE | AFTER} {INSERT | UPDATE | DELETE}
ON 表名
FOR EACH ROW
触发器逻辑;
- 触发时机 :
BEFORE
:在事件发生之前执行。AFTER
:在事件发生之后执行。
- 触发事件 :
INSERT
:插入新数据时触发。UPDATE
:更新数据时触发。DELETE
:删除数据时触发。
- 触发器逻辑 :
BEGIN
和END
包含的多条 SQL 语句。
2.2 删除触发器
sql
DROP TRIGGER [IF EXISTS] 触发器名;
2.3 查看触发器
sql
SHOW TRIGGERS;
3. 使用场景
3.1 日志记录
在表发生数据变更时,将操作记录到日志表中。
3.2 自动计算
根据插入或更新的值自动更新其他表或字段。
3.3 数据验证
在插入或更新数据前检查合法性。
3.4 联动更新
修改某表数据时,自动同步更新关联表数据。
4. 案例
4.1 日志记录案例
需求
在 employees
表中插入新员工时,将操作记录到 employee_logs
表中。
表结构
sql
CREATE TABLE employees (
emp_id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(100),
position VARCHAR(50),
salary DECIMAL(10, 2)
);
CREATE TABLE employee_logs (
log_id INT PRIMARY KEY AUTO_INCREMENT,
emp_id INT,
log_time DATETIME,
action VARCHAR(50)
);
创建触发器
sql
DELIMITER $$
CREATE TRIGGER trg_employee_insert
AFTER INSERT ON employees
FOR EACH ROW
BEGIN
INSERT INTO employee_logs (emp_id, log_time, action)
VALUES (NEW.emp_id, NOW(), 'INSERT');
END$$
DELIMITER ;
NEW
关键字:表示新插入的行数据。- 触发逻辑 :在插入
employees
表后,将信息记录到日志表中。
测试触发器
sql
INSERT INTO employees (name, position, salary)
VALUES ('Alice', 'Manager', 8000.00);
SELECT * FROM employee_logs;
4.2 数据验证案例
需求
禁止在 employees
表中插入薪资低于 3000 的员工。
创建触发器
sql
DELIMITER $$
CREATE TRIGGER trg_employee_salary_check
BEFORE INSERT ON employees
FOR EACH ROW
BEGIN
IF NEW.salary < 3000 THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'Salary must be at least 3000';
END IF;
END$$
DELIMITER ;
SIGNAL
语句:用于抛出自定义错误。- 触发逻辑:在插入之前检查薪资是否符合要求。
测试触发器
sql
INSERT INTO employees (name, position, salary)
VALUES ('Bob', 'Developer', 2000); -- 触发错误
4.3 联动更新案例
需求
当更新 employees
表的员工薪资时,将变更记录到 employee_logs
表中。
创建触发器
sql
DELIMITER $$
CREATE TRIGGER trg_employee_update
AFTER UPDATE ON employees
FOR EACH ROW
BEGIN
INSERT INTO employee_logs (emp_id, log_time, action)
VALUES (OLD.emp_id, NOW(), CONCAT('UPDATE: ', OLD.salary, ' -> ', NEW.salary));
END$$
DELIMITER ;
OLD
关键字:表示更新前的行数据。- 触发逻辑:记录薪资变更的详细信息。
测试触发器
sql
UPDATE employees
SET salary = 9000
WHERE emp_id = 1;
SELECT * FROM employee_logs;
5. 注意事项
- 触发器的数量限制 :每个表每种事件最多只能有一个
BEFORE
和一个AFTER
触发器。 - 性能影响:触发器的执行会增加额外的系统开销,建议在必要时使用。
- 错误处理 :在触发器中使用
SIGNAL
语句处理业务逻辑错误。 - 事务支持:触发器的执行与其事件处于同一事务中,事务回滚会撤销触发器的操作。
以上内容涵盖了 MySQL 触发器的概述、语法、使用场景及实践案例,帮助您更高效地利用触发器实现数据库操作自动化。