- 什么是 MySQL 触发器?
- 触发器是与表相关的数据库对象,当对表执行特定的操作(如 INSERT、UPDATE、DELETE)时,触发器会自动执行。它就像是一个在后台默默工作的 “小机器人”,一旦监听到指定的事件发生,就会按照预先定义的规则进行操作。
- 创建一个简单的 INSERT 触发器示例
- 假设我们有两个表:
orders
(订单表)和order_logs
(订单日志表)。每当在orders
表中插入一条新订单记录时,我们希望在order_logs
表中自动插入一条日志记录,记录订单的插入时间。 - 首先,创建
orders
表:CREATE TABLE orders ( order_id INT AUTO_INCREMENT PRIMARY KEY, customer_name VARCHAR(255), order_date DATE );
- 然后,创建
order_logs
表:CREATE TABLE order_logs ( log_id INT AUTO_INCREMENT PRIMARY KEY, order_id INT, action VARCHAR(10), log_date TIMESTAMP );
- 现在,创建 INSERT 触发器:
DELIMITER // CREATE TRIGGER after_order_insert AFTER INSERT ON orders FOR EACH ROW BEGIN INSERT INTO order_logs (order_id, action, log_date) VALUES (NEW.order_id, 'INSERT', NOW()); END // DELIMITER ;
- 解释:
DELIMITER //
:这是因为在 MySQL 中,触发器的主体部分(BEGIN
和END
之间)包含多条 SQL 语句,默认情况下,;
是 SQL 语句的结束符。所以我们先将结束符修改为//
,这样在定义触发器时,MySQL 就知道整个BEGIN
-END
块是一个整体。CREATE TRIGGER after_order_insert
:创建一个名为after_order_insert
的触发器。AFTER INSERT ON orders
:指定这个触发器在orders
表执行 INSERT 操作之后触发。FOR EACH ROW
:表示对于orders
表中插入的每一行数据,都会执行触发器中的操作。- 在
BEGIN
-END
块中:INSERT INTO order_logs (order_id, action, log_date)
:向order_logs
表插入一条记录。VALUES (NEW.order_id, 'INSERT', NOW())
:这里的NEW
是一个特殊的关键字,当在orders
表插入新行时,NEW
代表新插入的行。NEW.order_id
就是新插入订单的order_id
,action
设置为INSERT
表示插入操作,log_date
使用NOW()
函数获取当前时间。
- 测试触发器:
INSERT INTO orders (customer_name, order_date) VALUES ('John Doe', '2024-01-01');
- 当执行这条插入订单的 SQL 语句后,MySQL 会自动在
order_logs
表中插入一条对应的日志记录,记录了订单的插入操作和时间。
- 当执行这条插入订单的 SQL 语句后,MySQL 会自动在
- 假设我们有两个表:
- UPDATE 触发器示例
- 假设我们希望在更新
orders
表中的order_date
字段时,在order_logs
表中记录更新操作。 - 创建 UPDATE 触发器:
DELIMITER // CREATE TRIGGER after_order_update AFTER UPDATE ON orders FOR EACH ROW BEGIN IF NEW.order_date <> OLD.order_date THEN INSERT INTO order_logs (order_id, action, log_date) VALUES (NEW.order_id, 'UPDATE', NOW()); END IF; END // DELIMITER ;
- 解释:
AFTER UPDATE ON orders
:这个触发器在orders
表执行 UPDATE 操作之后触发。- 在
BEGIN
-END
块中:IF NEW.order_date <> OLD.order_date THEN
:OLD
是另一个特殊关键字,代表更新操作之前的行。这里判断如果更新后的order_date
和更新前的order_date
不同,就执行下面的插入操作。- 插入操作与前面 INSERT 触发器中的类似,只是
action
设置为UPDATE
。
- 假设我们希望在更新
- DELETE 触发器示例
- 假设我们希望在删除
orders
表中的记录时,在order_logs
表中记录删除操作。 - 创建 DELETE 触发器:
DELIMITER // CREATE TRIGGER after_order_delete AFTER DELETE ON orders FOR EACH ROW BEGIN INSERT INTO order_logs (order_id, action, log_date) VALUES (OLD.order_id, 'DELETE', NOW()); END // DELIMITER ;
- 解释:
AFTER DELETE ON orders
:这个触发器在orders
表执行 DELETE 操作之后触发。- 在插入操作中,使用
OLD.order_id
来获取被删除订单的order_id
,action
设置为DELETE
。
- 假设我们希望在删除