MySQL 触发器(Trigger)是一种特殊的存储过程,它在特定事件(INSERT、UPDATE、DELETE)发生时自动执行。触发器可以帮助我们实现数据完整性约束、审计跟踪、自动计算等需求。
触发器是与表相关联的数据库对象,当表发生特定事件时自动执行。触发器的主要特点:
CREATE TRIGGER trigger_name
{BEFORE | AFTER} {INSERT | UPDATE | DELETE}
ON table_name FOR EACH ROW
trigger_body
-- 创建测试表
CREATE TABLE products (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100),
price DECIMAL(10,2),
last_updated TIMESTAMP
);
-- 创建触发器:在更新时自动设置last_updated字段
DELIMITER //
CREATE TRIGGER update_product_timestamp
BEFORE UPDATE ON products
FOR EACH ROW
BEGIN
SET NEW.last_updated = CURRENT_TIMESTAMP;
END//
DELIMITER ;
-- 测试触发器
INSERT INTO products (name, price) VALUES ('Laptop', 999.99);
UPDATE products SET price = 899.99 WHERE name = 'Laptop';
-- 查看结果,last_updated字段会自动更新
-- 创建触发器:确保价格不为负
DELIMITER //
CREATE TRIGGER check_product_price
BEFORE INSERT ON products
FOR EACH ROW
BEGIN
IF NEW.price < 0 THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'Price cannot be negative';
END IF;
END//
DELIMITER ;
-- 测试触发器
INSERT INTO products (name, price) VALUES ('Invalid Product', -10);
-- 这将触发错误:Price cannot be negative
-- 创建审计日志表
CREATE TABLE product_audit (
id INT AUTO_INCREMENT PRIMARY KEY,
product_id INT,
old_price DECIMAL(10,2),
new_price DECIMAL(10,2),
changed_by VARCHAR(100),
changed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 创建触发器:记录价格变更
DELIMITER //
CREATE TRIGGER log_price_change
AFTER UPDATE ON products
FOR EACH ROW
BEGIN
IF OLD.price != NEW.price THEN
INSERT INTO product_audit (
product_id, old_price, new_price, changed_by
) VALUES (
NEW.id, OLD.price, NEW.price, CURRENT_USER()
);
END IF;
END//
DELIMITER ;
-- 测试触发器
UPDATE products SET price = 799.99 WHERE name = 'Laptop';
-- 查看product_audit表,会有一条新记录
-- 创建订单和订单明细表
CREATE TABLE orders (
order_id INT AUTO_INCREMENT PRIMARY KEY,
order_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
total_amount DECIMAL(10,2) DEFAULT 0
);
CREATE TABLE order_items (
item_id INT AUTO_INCREMENT PRIMARY KEY,
order_id INT,
product_name VARCHAR(100),
quantity INT,
unit_price DECIMAL(10,2),
subtotal DECIMAL(10,2),
FOREIGN KEY (order_id) REFERENCES orders(order_id)
);
-- 创建触发器:插入订单明细时更新订单总额
DELIMITER //
CREATE TRIGGER update_order_total
AFTER INSERT ON order_items
FOR EACH ROW
BEGIN
UPDATE orders
SET total_amount = total_amount + NEW.subtotal
WHERE order_id = NEW.order_id;
END//
DELIMITER ;
-- 创建触发器:删除订单明细时更新订单总额
DELIMITER //
CREATE TRIGGER update_order_total_delete
AFTER DELETE ON order_items
FOR EACH ROW
BEGIN
UPDATE orders
SET total_amount = total_amount - OLD.subtotal
WHERE order_id = OLD.order_id;
END//
DELIMITER ;
-- 测试触发器
INSERT INTO orders (order_date) VALUES (CURRENT_TIMESTAMP);
INSERT INTO order_items (order_id, product_name, quantity, unit_price, subtotal)
VALUES (1, 'Laptop', 1, 799.99, 799.99);
-- 查看orders表,total_amount会自动更新
-- 查看所有触发器
SHOW TRIGGERS;
-- 查看特定触发器的定义
SHOW CREATE TRIGGER trigger_name;
MySQL 不支持直接修改触发器,需要先删除再重新创建:
DROP TRIGGER IF EXISTS trigger_name;
-- 然后重新创建触发器
DROP TRIGGER [IF EXISTS] trigger_name;
MySQL 触发器是强大的自动化工具,可以用于: - 自动维护数据完整性 - 实现审计跟踪 - 自动计算派生数据 - 执行复杂业务规则
合理使用触发器可以减少应用层代码,提高数据一致性,但也要注意避免过度使用导致系统难以维护。