求助编写PostgreSQL通用审计触发器:实现system表日志记录
实现system表操作审计的触发器与函数方案
没问题,我来帮你搞定这个记录所有表操作的审计需求!下面是针对PostgreSQL环境的完整实现代码(如果是MySQL等其他数据库,语法会略有不同,但核心逻辑一致):
1. 创建审计处理函数
先写一个PL/pgSQL函数,用来识别操作类型、捕获对应数据并写入system_audit日志表:
CREATE OR REPLACE FUNCTION audit_system_changes() RETURNS TRIGGER AS $$ BEGIN -- 根据触发的操作类型,写入对应数据到审计表 CASE TG_OP WHEN 'INSERT' THEN INSERT INTO system_audit ( -- 替换成你system表的实际列名,比如id, name, status... id, name, status, modified_dt, modified_by, modified_type ) VALUES ( NEW.id, NEW.name, NEW.status, NOW(), CURRENT_USER, 'INSERT' ); RETURN NEW; WHEN 'UPDATE' THEN INSERT INTO system_audit ( id, name, status, modified_dt, modified_by, modified_type ) VALUES ( NEW.id, NEW.name, NEW.status, NOW(), CURRENT_USER, 'UPDATE' ); RETURN NEW; WHEN 'DELETE' THEN INSERT INTO system_audit ( id, name, status, modified_dt, modified_by, modified_type ) VALUES ( OLD.id, OLD.name, OLD.status, NOW(), CURRENT_USER, 'DELETE' ); RETURN OLD; ELSE RETURN NULL; END CASE; END; $$ LANGUAGE plpgsql;
函数细节说明:
TG_OP是触发器内置变量,自动获取当前触发的操作类型(INSERT/UPDATE/DELETE)NEW代表操作后的新数据行(仅INSERT/UPDATE场景可用),OLD代表操作前的旧数据行(仅UPDATE/DELETE场景可用)NOW()获取当前时间戳,CURRENT_USER直接拿到执行操作的数据库用户- 务必把代码里的示例列(
id, name, status)替换成你system表的真实列名,要和system_audit表的列完全对应
2. 创建绑定触发器
接着创建一个AFTER触发器,把它绑定到system表,触发所有写操作时自动调用上面的函数:
CREATE TRIGGER trigger_system_audit AFTER INSERT OR UPDATE OR DELETE ON system FOR EACH ROW EXECUTE FUNCTION audit_system_changes();
触发器细节说明:
AFTER表示在原操作(插入/更新/删除)完成后再执行审计逻辑,不会干扰原业务操作的执行FOR EACH ROW确保每一行数据的变化都会触发一次函数,保证每条操作都被精准记录
额外实用提示
- 如果后续
system表有列结构变更,记得同步更新system_audit表的结构,以及审计函数里的列列表 - 要是你需要适配多表的通用审计方案,可以用动态SQL自动获取表列,但单表场景下上面的方案更简单直观
- 可以根据需求扩展
modified_type的取值,比如区分批量操作还是单行操作,但基础场景下INSERT/UPDATE/DELETE足够满足需求
内容的提问来源于stack exchange,提问作者Anish Gopinath
相关产品推荐
相关产品推荐

