Postgresql 多表审计触发函数

Postgresql 多表审计触发函数,postgresql,triggers,plpgsql,Postgresql,Triggers,Plpgsql,我想保留我的表的所有更改。我有一个为每个表创建触发器的有效解决方案,但是复制每个表的代码似乎很愚蠢。有没有办法创建一个单触发器函数来实现这一点 每个表触发器的工作示例(包括表定义): 我尝试通过将“\u hist”连接到TG\u table\u NAME,使其成为多表: CREATE OR REPLACE FUNCTION add_to_hist_table() RETURNS TRIGGER AS $$ DECLARE histTable text :=TG_TABLE_NAME ||

我想保留我的表的所有更改。我有一个为每个表创建触发器的有效解决方案,但是复制每个表的代码似乎很愚蠢。有没有办法创建一个单触发器函数来实现这一点

每个表触发器的工作示例(包括表定义):

我尝试通过将“\u hist”连接到TG\u table\u 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
我想这是变量替换()的问题

如何实现这一功能


另外,我正在使用postgresql 8.4,但可能很快就会升级到9.3。

我找到了解决这个“相关问题”的方法

我没有想过对新的和旧的进行“执行-使用”。因此,现在一个可行的解决方案是:

CREATE OR REPLACE FUNCTION add_to_hist_table() RETURNS TRIGGER AS $$
BEGIN
IF (TG_OP='INSERT' OR TG_OP='UPDATE') THEN
    execute 'INSERT INTO '|| TG_TABLE_NAME ||'_hist values (''' || TG_OP || ''',date_part(''epoch'', NOW()),DEFAULT,$1.*)' using NEW;
ELSIF TG_OP='DELETE' THEN
    execute 'INSERT INTO '|| TG_TABLE_NAME ||'_hist values (''' || TG_OP || ''',date_part(''epoch'', NOW()),DEFAULT,$1.*)'  using OLD;
END IF;
RETURN null; --ignored since it is an AFTER triggger.
END;
$$ LANGUAGE plpgsql;

@Pascal_dher,有人可以用包含攻击者代码的名称创建表。由于Postgresql,这可能不会执行一些非常糟糕的、只有失败的查询。但是,如果您的触发器更复杂,那么影响可能更糟糕。

注意-此示例易受SQL注入的影响。任何参数都是动态的,查询字符串必须经过清理(转义)。hi@PavelStehule。它是如何或在哪里?(这是一个触发器,我不使用任何未经postgres解释的用户输入变量)@PavelStehule您能指出它在哪里是vurnable或演示更好的解决方案吗?谢谢:-)但是如果他们能在开发之前创建表,难道他们不能做所有的事情吗?使用quote_ident(tg_table_name | | |“u hist”)和quote_literal(tg_op)可以修复潜在的sql注入吗?
CREATE OR REPLACE FUNCTION add_to_hist_table() RETURNS TRIGGER AS $$
BEGIN
IF (TG_OP='INSERT' OR TG_OP='UPDATE') THEN
    execute 'INSERT INTO '|| TG_TABLE_NAME ||'_hist values (''' || TG_OP || ''',date_part(''epoch'', NOW()),DEFAULT,$1.*)' using NEW;
ELSIF TG_OP='DELETE' THEN
    execute 'INSERT INTO '|| TG_TABLE_NAME ||'_hist values (''' || TG_OP || ''',date_part(''epoch'', NOW()),DEFAULT,$1.*)'  using OLD;
END IF;
RETURN null; --ignored since it is an AFTER triggger.
END;
$$ LANGUAGE plpgsql;