PostgreSQL从入门到进阶
🏠 首页
  • 开始学习

    • PostgreSQL介绍
    • 安装配置
  • 基础教程

    • 数据库与表
    • 数据类型
    • CRUD操作
    • WHERE条件
  • 进阶查询

    • 联表查询
    • 聚合函数
    • 子查询
    • 视图
  • 性能优化

    • 索引优化
    • 查询优化
    • EXPLAIN分析
  • 事务处理
  • 触发器
  • 存储过程
  • JSON数据
  • 博客系统
  • 用户管理系统
  • 最佳实践
🔗 编程指南
🏠 首页
  • 开始学习

    • PostgreSQL介绍
    • 安装配置
  • 基础教程

    • 数据库与表
    • 数据类型
    • CRUD操作
    • WHERE条件
  • 进阶查询

    • 联表查询
    • 聚合函数
    • 子查询
    • 视图
  • 性能优化

    • 索引优化
    • 查询优化
    • EXPLAIN分析
  • 事务处理
  • 触发器
  • 存储过程
  • JSON数据
  • 博客系统
  • 用户管理系统
  • 最佳实践
🔗 编程指南
  • 开始之前

    • 教程介绍
    • 什么是PostgreSQL?
    • 安装PostgreSQL
  • 基础入门

    • 数据库和表的概念
    • 数据类型详解
    • 增删改查操作(CRUD)
    • 查询条件WHERE
  • 进阶查询

    • 多表联查JOIN
    • 聚合函数
    • 子查询
    • 视图VIEW
  • 性能优化

    • 索引详解
    • 查询优化
    • 执行计划分析
  • 高级特性

    • 事务处理
    • 触发器
    • 存储过程
    • JSON数据
  • 实战项目

    • 实战项目:博客系统
    • 实战项目:用户管理系统
    • 最佳实践

触发器

嗨!我是长安。触发器让数据库"自动化"!

🎯 什么是触发器?

触发器是自动执行的函数,在INSERT/UPDATE/DELETE时触发。

-- 每次插入用户时,自动记录日志
CREATE TRIGGER log_new_user
AFTER INSERT ON users
FOR EACH ROW
EXECUTE FUNCTION log_user_creation();

📝 创建触发器

第一步:创建触发器函数

-- 创建函数
CREATE OR REPLACE FUNCTION update_timestamp()
RETURNS TRIGGER AS $$
BEGIN
    NEW.updated_at = NOW();
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

第二步:创建触发器

-- 创建触发器
CREATE TRIGGER trigger_update_timestamp
BEFORE UPDATE ON posts
FOR EACH ROW
EXECUTE FUNCTION update_timestamp();

现在每次UPDATE posts时,updated_at会自动更新!

🎯 触发器类型

BEFORE触发器

在操作之前执行,可以修改数据:

CREATE OR REPLACE FUNCTION check_age()
RETURNS TRIGGER AS $$
BEGIN
    IF NEW.age < 0 OR NEW.age > 150 THEN
        RAISE EXCEPTION '年龄不合法: %', NEW.age;
    END IF;
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER trigger_check_age
BEFORE INSERT OR UPDATE ON users
FOR EACH ROW
EXECUTE FUNCTION check_age();

AFTER触发器

在操作之后执行,用于记录日志:

CREATE OR REPLACE FUNCTION log_user_changes()
RETURNS TRIGGER AS $$
BEGIN
    INSERT INTO user_logs (user_id, action, changed_at)
    VALUES (NEW.id, TG_OP, NOW());
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER trigger_log_changes
AFTER INSERT OR UPDATE OR DELETE ON users
FOR EACH ROW
EXECUTE FUNCTION log_user_changes();

💡 实战案例

自动更新统计

-- 文章表
CREATE TABLE posts (
    id SERIAL PRIMARY KEY,
    user_id INT,
    title VARCHAR(200)
);

-- 用户统计表
CREATE TABLE user_stats (
    user_id INT PRIMARY KEY,
    post_count INT DEFAULT 0
);

-- 触发器函数
CREATE OR REPLACE FUNCTION update_post_count()
RETURNS TRIGGER AS $$
BEGIN
    IF TG_OP = 'INSERT' THEN
        INSERT INTO user_stats (user_id, post_count)
        VALUES (NEW.user_id, 1)
        ON CONFLICT (user_id) 
        DO UPDATE SET post_count = user_stats.post_count + 1;
    ELSIF TG_OP = 'DELETE' THEN
        UPDATE user_stats 
        SET post_count = post_count - 1
        WHERE user_id = OLD.user_id;
    END IF;
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

-- 创建触发器
CREATE TRIGGER trigger_update_post_count
AFTER INSERT OR DELETE ON posts
FOR EACH ROW
EXECUTE FUNCTION update_post_count();

软删除

CREATE OR REPLACE FUNCTION soft_delete()
RETURNS TRIGGER AS $$
BEGIN
    UPDATE users 
    SET is_deleted = TRUE, deleted_at = NOW()
    WHERE id = OLD.id;
    RETURN NULL;  -- 阻止真实的DELETE
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER trigger_soft_delete
BEFORE DELETE ON users
FOR EACH ROW
EXECUTE FUNCTION soft_delete();

🛠️ 管理触发器

-- 查看触发器
\dS table_name

-- 禁用触发器
ALTER TABLE users DISABLE TRIGGER trigger_name;

-- 启用触发器
ALTER TABLE users ENABLE TRIGGER trigger_name;

-- 删除触发器
DROP TRIGGER trigger_name ON users;

📚 下一步

触发器很强大,但不要滥用!

继续学习存储过程!


长安提醒:触发器会影响性能,复杂逻辑建议在应用层处理!⚡

最近更新: 2025/12/1 18:21
Prev
事务处理
Next
存储过程