pgsql-13 触发器详解
目录
13 - 触发器详解
1. 📖 概述
触发器是在特定事件(INSERT/UPDATE/DELETE)发生时自动执行的函数。本章介绍PostgreSQL触发器的使用。
2. 🔔 触发器基础
2.1 创建触发器
-- 1. 创建触发器函数
CREATE OR REPLACE FUNCTION update_timestamp()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = NOW();
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
-- 2. 创建触发器
CREATE TRIGGER trigger_update_timestamp
BEFORE UPDATE ON users
FOR EACH ROW
EXECUTE FUNCTION update_timestamp();
-- 测试
UPDATE users SET username = 'new_name' WHERE id = 1;
-- updated_at会自动更新
2.2 触发器时机
-- BEFORE: 在操作执行前
CREATE TRIGGER before_insert
BEFORE INSERT ON products
FOR EACH ROW
EXECUTE FUNCTION validate_product();
-- AFTER: 在操作执行后
CREATE TRIGGER after_insert
AFTER INSERT ON orders
FOR EACH ROW
EXECUTE FUNCTION send_order_notification();
-- INSTEAD OF: 仅用于视图,替代原操作
CREATE TRIGGER instead_of_update
INSTEAD OF UPDATE ON view_name
FOR EACH ROW
EXECUTE FUNCTION custom_update();
3. 💡 实用示例
3.1 审计日志
CREATE TABLE audit_log (
id SERIAL PRIMARY KEY,
table_name TEXT,
operation TEXT,
old_data JSONB,
new_data JSONB,
user_id INTEGER,
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE OR REPLACE FUNCTION audit_trigger()
RETURNS TRIGGER AS $$
BEGIN
INSERT INTO audit_log (table_name, operation, old_data, new_data, user_id)
VALUES (
TG_TABLE_NAME,
TG_OP,
row_to_json(OLD),
row_to_json(NEW),
current_setting('app.user_id', TRUE)::INTEGER
);
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER users_audit
AFTER INSERT OR UPDATE OR DELETE ON users
FOR EACH ROW
EXECUTE FUNCTION audit_trigger();
3.2 自动计算
-- 订单金额自动计算
CREATE OR REPLACE FUNCTION calculate_order_total()
RETURNS TRIGGER AS $$
BEGIN
UPDATE orders
SET total_amount = (
SELECT SUM(quantity * price)
FROM order_items
WHERE order_id = NEW.order_id
)
WHERE id = NEW.order_id;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER trigger_calculate_total
AFTER INSERT OR UPDATE OR DELETE ON order_items
FOR EACH ROW
EXECUTE FUNCTION calculate_order_total();
4. 📚 下一步
学习事务与并发控制
关键要点:
- BEFORE触发器可以修改NEW
- AFTER触发器不能修改数据
- 避免触发器死循环
- 审计日志常用触发器实现
xingliuhua