如何设置Postgresql审核触发器的用户名?

时间:2009-07-14 16:48:54

标签: database database-design triggers audit auditing

我在PostgreSQL 8.2中使用触发器来审核对表的更改:

CREATE OR REPLACE FUNCTION update_issue_history() RETURNS trigger as $trig$
BEGIN
        INSERT INTO issue_history (username, issueid)
               VALUES ('fixed-username', OLD.issueid);
        RETURN NULL;
END;
$trig$ LANGUAGE plpgsql;

CREATE TRIGGER update_issue_history_trigger
AFTER UPDATE ON issue
      FOR EACH ROW EXECUTE PROCEDURE update_issue_history();

我想要做的是在执行更新时提供fixed-username的值。这可能吗?如果是这样,我该如何完成它?

2 个答案:

答案 0 :(得分:0)

尝试这样的事情:

CREATE OR REPLACE FUNCTION update_issue_history() 
RETURNS trigger as $trig$
DECLARE
      arg_username varchar;
BEGIN
      arg_username := TG_ARGV[0];
      INSERT INTO issue_history (username, issueid)
             VALUES (arg_username, OLD.issueid);
      RETURN NULL;
END;
$trig$ LANGUAGE plpgsql;

CREATE TRIGGER update_issue_history_trigger
AFTER UPDATE ON issue
      FOR EACH ROW EXECUTE PROCEDURE update_issue_history('my username value');

答案 1 :(得分:0)

除了创建临时表并在触发器中使用EXECUTE之外,我没有看到这样做的方法。但这会产生性能影响。一个更好的选择可能是在某个地方绑定另一个表并登录谁通过会话ID和后端PID登录/注销,并引用它?

请注意,您没有任何其他方法可以将信息输入更新语句。请记住,触发器只能查看API或数据库中可用的内容。如果您希望触发器透明地工作,您不能指望在运行时将信息传递给它,否则它将无法访问它。

你要问的基本问题是“数据库如何知道放在那里的内容?”一旦你决定了一种方法,答案应该是直截了当的,但是没有免费的午餐。

<强>更新

过去当我使用应用程序角色登录db时我不得不做这样的事情,我这样做的方法是创建一个临时表,然后从存储过程中访问该表。当前存储过程可以通过这种方式处理临时表,但在过去我们必须使用EXECUTE。

这种方法有两个很大的局限性。第一个是它创建了很多表,这最终导致了oid环绕的可能性。

这些天我更喜欢将db登录到用户登录。这使得管理变得更加容易,您只需通过值SESSION_USER进行访问(新手错误就是使用CURRENT_USER来显示当前的安全上下文而不是用户的登录信息。

这些方法都不适用于连接池。在第一种情况下,您无法进行连接池,因为您的临时表将被误解或破坏。在第二种情况下,您无法执行此操作,因为登录角色不同。