1

I am using a trigger in PostgreSQL 8.2 to audit changes to a table:

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();

What I want to do is have some way to provide the value of fixed-username at the time that I execute the update. Is this possible? If so, how do I accomplish it?

4

2 回答 2

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');
于 2009-07-14T16:58:30.633 回答
0

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

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

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

更新

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

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

这些天来,我更喜欢将数据库的登录名作为用户登录名。这使得这更容易管理,您可以通过值访问SESSION_USER(一个新手错误是使用CURRENT_USER它向您显示当前的安全上下文而不是用户的登录名。

这些方法都不适用于连接池。在第一种情况下,您不能进行连接池,因为您的临时表会被误解或破坏。第二种,你不能这样做,因为登录角色不同。

于 2012-10-02T01:01:00.667 回答