我想保留我的表的所有更改。我有一個工作解決方案爲每個表格創建一個觸發器,但是複製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。
注意 - 此示例易受SQL注入攻擊。任何參數都是動態查詢字符串必須清理(轉義)。 –
hi @PavelStehule。它如何或在哪裏是可以虛擬的? (這是一個觸發器,我不使用任何用戶輸入的變量,但尚未被postgres解釋) –
@PavelStehule您能否指出它可以在哪裏使用或演示更好的解決方案?謝謝:-) –