2009-07-14 67 views
1

我使用PostgreSQL中8.2触发审计变为表:如何为Postgresql审计触发器设置用户名?

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值。这可能吗?如果是这样,我该如何实现它?

+0

[Passing user编号为PostgreSQL触发器](http://stackoverflow.com/questions/13172524/passing-user-id-to-postgresql-triggers) – 2013-03-10 08:24:24

回答

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'); 
0

我没有看到一个办法做到这一点以外,以创建临时表和使用EXECUTE您的触发器。尽管如此,这会产生性能影响。一个更好的选择可能是绑定到另一个表的某处并登录登录/注销会话ID和后端PID,并引用它?

请注意,您没有任何其他方式将信息获取到更新声明中。请记住,触发器只能查看API或数据库中可用的内容。如果你想让一个触发器透明工作,你不能期望在运行时将信息传递给它,否则就无法访问它。

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

更新

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

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

这些天我更喜欢登录到数据库是用户登录。这使得这更容易管理,你可以直接通过值SESSION_USER访问(一个新手的错误是使用CURRENT_USER这表明你当前的安全上下文,而不是用户的登录。

这些都不方法工作得很好用连接池在第一种情况下,你不能连接池,因为你的临时表会被误解或破坏;第二种情况,你不能这样做,因为登录角色不同,