目录
一、定义
触发器是一种特殊的存储过程(Stored Procedure),它不像普通的存储过程需要被显式调用,而是在特定的数据库事件发生时自动执行。这些事件通常与数据修改操作(如 INSERT, UPDATE, DELETE)或数据库结构变化(如 CREATE, ALTER, DROP)相关联。
触发器与存储过程的区别:
- 触发器自动执行,不能手动调用。
- 触发器通常与表绑定,针对特定事件。
二、类型
触发器根据触发时机和触发事件的不同,可以分为不同的类型。
- 触发事件:触发器可以与 INSERT、UPDATE、DELETE 这三种数据库操作关联。
- 触发时机:触发器可以在数据操作的 前(BEFORE)或 后(AFTER)执行。
三、基本语法
CREATE TRIGGER trigger_name
{BEFORE | AFTER} {INSERT | UPDATE | DELETE}
ON table_name
FOR EACH ROW
[trigger_body];
trigger_name
:触发器的名称。BEFORE
或AFTER
:指定触发时机,表示事件发生之前或之后触发。INSERT
、UPDATE
或DELETE
:指定触发的数据库事件。table_name
:触发器关联的表。FOR EACH ROW
:表示对于每一行数据的变动都会执行触发器。trigger_body
:触发器的执行内容,通常是一些 SQL 操作。
四、实际应用
示例1:BEFORE 触发器(操作前触发)
应用场景:用于数据验证或修改待插入/更新的数据。
假定有Orders
表,要求 total_amount
必须大于 0。
CREATE TRIGGER check_order_amount
BEFORE INSERT ON Orders
FOR EACH ROW
BEGIN
-- 如果插入的订单金额小于等于0,则抛出错误
IF NEW.total_amount <= 0 THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Order amount must be greater than zero';
END IF;
END;
BEFORE INSERT
表示触发器会在插入数据之前触发。NEW.total_amount
是对新插入数据的引用,NEW
代表即将插入的行数据。SIGNAL SQLSTATE '45000'
用来抛出一个自定义错误消息,如果条件不满足,数据插入将会被拒绝。
在
BEFORE INSERT
和AFTER INSERT
触发器中,NEW
代表将要插入或已经插入的新行在
BEFORE UPDATE
和AFTER UPDATE
触发器中,NEW
代表更新后的新数据,OLD
代表更新前的旧数据在
BEFORE DELETE
和AFTER DELETE
触发器中,只有OLD
可用,代表被删除的行
示例2:AFTER 触发器(操作后触发)
应用场景:用于执行与数据操作相关的后处理任务,例如日志记录、自动同步等。
假定有 Customers
表,希望在更新客户信息时自动记录日志。
CREATE TRIGGER log_customer_update
AFTER UPDATE ON Customers
FOR EACH ROW
BEGIN
INSERT INTO AuditLogs (Action, TableName, OldValue, NewValue, ActionDate)
VALUES ('UPDATE', 'Customers', OLD.name, NEW.name, NOW());
END;
AFTER UPDATE
表示触发器会在更新操作完成后触发。OLD.name
和NEW.name
分别表示更新前后的值。NOW()
获取当前时间,记录到日志表中。
示例3: INSTEAD OF 触发器(替代操作触发器)
应用场景:用于视图的插入、更新和删除操作。通常用于对视图进行修改时,定义如何转换为底层表的操作。
假定有视图 CustomerView
,当对该视图进行更新时,希望将更新操作实际应用于 Customers
表。
CREATE TRIGGER instead_of_update_customer
INSTEAD OF UPDATE ON CustomerView
FOR EACH ROW
BEGIN
UPDATE Customers
SET name = NEW.name, address = NEW.address
WHERE customer_id = OLD.customer_id;
END;
示例4:DELETE 触发器(删除操作触发)
应用场景:用于处理数据删除时的相关操作,比如清理相关表的数据、发送通知等。
假定有 Orders
表,如果删除一个订单记录,想要自动删除该订单下的所有订单项。
CREATE TRIGGER delete_order_items
AFTER DELETE ON Orders
FOR EACH ROW
BEGIN
DELETE FROM OrderItems WHERE order_id = OLD.order_id;
END;
五、思考总结
触发器是数据库管理系统中不可忽视的强大工具,它能显著提升数据库自动化处理的能力、保证数据一致性和执行效率。但同时,触发器的设计和使用也需要谨慎,特别是在高并发、数据量大或逻辑复杂的场景下,我们需要注意触发器的性能影响、事务管理以及与业务逻辑的分离问题。