【发布时间】:2016-02-02 21:01:47
【问题描述】:
我想保留我的表格的所有更改。我有一个为每个表创建触发器的工作解决方案,但复制代码 foreach 表似乎很愚蠢。有没有办法创建一个这样的触发函数?
我的工作表触发器示例(包括表定义):
CREATE TABLE departments (
id bigserial Primary Key,
name varchar not null,
created bigint not null default date_part('epoch', NOW()),
created_by bigint references Employees (id) not null
);
create table Departments_hist ("action" varchar not null, change_date bigint not null, rev bigserial not null, like Departments);
CREATE OR REPLACE FUNCTION add_to_history_Departments() RETURNS TRIGGER AS $$
BEGIN
IF(TG_OP='INSERT' OR TG_OP='UPDATE') THEN
INSERT INTO Departments_hist values (TG_OP,date_part('epoch', NOW()),DEFAULT,NEW.*);
END IF;
IF (TG_OP='DELETE') THEN
INSERT INTO Departments_hist values (TG_OP,date_part('epoch', NOW()),DEFAULT,OLD.*);
END IF;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER trigger_history_Departments AFTER INSERT OR UPDATE OR DELETE ON Departments FOR EACH ROW EXECUTE PROCEDURE add_to_history_Departments();
我尝试通过将 '_hist' 连接到 TG_TABLE_NAME 来使其成为多表:
CREATE OR REPLACE FUNCTION add_to_hist_table() RETURNS TRIGGER AS $$
DECLARE
histTable text :=TG_TABLE_NAME || '_hist';
BEGIN
IF (TG_OP='INSERT' OR TG_OP='UPDATE') THEN
INSERT INTO histTable values (TG_OP,date_part('epoch', NOW()),DEFAULT,NEW.*);
ELSIF TG_OP='DELETE' THEN
INSERT INTO histTable values (TG_OP,date_part('epoch', NOW()),DEFAULT,OLD.*);
END IF;
RETURN null; --ignored since it is an AFTER triggger.
END;
$$ LANGUAGE plpgsql;
但我得到一个错误:
ERROR: syntax error at or near "$1"
LINE 1: INSERT INTO $1 values ( $2 ,date_part('epoch', NOW()),DEFA...
^
QUERY: INSERT INTO $1 values ( $2 ,date_part('epoch', NOW()),DEFAULT, $3 .*)
CONTEXT: SQL statement in PL/PgSQL function "add_to_hist_table" near line 5
我猜这是变量替换的问题 (http://www.postgresql.org/docs/8.4/static/plpgsql-implementation.html)。
如何实现这个功能?
PS。我正在使用 postgresql 8.4,但可能很快会升级到 9.3。
【问题讨论】:
标签: postgresql triggers plpgsql