【发布时间】:2016-01-29 08:02:16
【问题描述】:
所以我的问题很简单。我有一个架构prod 有很多表,另一个log 有完全相同的表和结构(主键改变就是这样)。
当我在架构prod 中执行UPDATE 或DELETE 时,我想在log 架构中记录旧数据。
我在更新或删除后调用了以下函数:
CREATE FUNCTION prod.log_data() RETURNS trigger
LANGUAGE plpgsql AS $$
DECLARE
v RECORD;
column_names text;
value_names text;
BEGIN
-- get column names of current table and store the list in a text var
column_names = '';
value_names = '';
FOR v IN SELECT * FROM information_schema.columns WHERE table_name = quote_ident(TG_TABLE_NAME) AND table_schema = quote_ident(TG_TABLE_SCHEMA) LOOP
column_names = column_names || ',' || v.column_name;
value_names = value_names || ',$1.' || v.column_name;
END LOOP;
-- remove first char ','
column_names = substring( column_names FROM 2);
value_names = substring( value_names FROM 2);
-- execute the insert into log schema
EXECUTE 'INSERT INTO log.' || TG_TABLE_NAME || ' ( ' || column_names || ' ) VALUES ( ' || value_names || ' )' USING OLD;
RETURN NULL; -- no need to return, it is executed after update
END;$$;
烦人的部分是我必须从information_schema 获取每一行的列名。
我宁愿用这个:
EXECUTE 'INSERT INTO log.' || TG_TABLE_NAME || ' SELECT ' || OLD;
但有些值可以是NULL,所以这会执行:
INSERT INTO log.user SELECT 2,,,"2015-10-28 13:52:44.785947" 代替 INSERT INTO log.user SELECT 2,NULL,NULL,"2015-10-28 13:52:44.785947"
有没有办法将",," 转换为",NULL,"?
谢谢
-昆汀
【问题讨论】:
标签: postgresql function triggers audit audit-logging