2009-07-14 4 views
1

J'utilise un déclencheur dans PostgreSQL 8.2 pour auditer des modifications à une table:Comment puis-je définir un nom d'utilisateur pour un déclencheur d'audit 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(); 

Ce que je veux faire est d'avoir un moyen de fournir au moment où la valeur de fixed-username que j'exécute la mise à jour. Est-ce possible? Si oui, comment l'accomplir?

+0

duplication possible de [Passing user id à PostgreSQL triggers] (http://stackoverflow.com/questions/13172524/passing-user-id-to-postgresql-triggers) –

+0

La réponse [ici] [1] résume assez bien. [1]: http://stackoverflow.com/a/13172964/947357 –

+0

8.2? Veuillez lire http://www.postgresql.org/support/versioning/ et commencer à planifier votre mise à niveau. –

Répondre

0

Essayez quelque chose comme ceci:

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

Je ne vois pas une façon de faire autre que de créer des tables temporaires et utiliser execute dans votre déclencheur. Cela aura des conséquences sur les performances. Une meilleure option pourrait être de lier dans une autre table quelque part et de se connecter qui se connecte/se déconnecte par ID de session et PID back-end, et référence cela?

Notez que vous n'avez aucun autre moyen d'obtenir les informations dans l'instruction de mise à jour. Gardez à l'esprit que le déclencheur ne peut voir que ce qui est disponible dans l'API ou dans la base de données. Si vous voulez qu'un déclencheur fonctionne de manière transparente, vous ne pouvez pas vous attendre à lui transmettre des informations à l'exécution auxquelles il n'aurait pas accès autrement.

La question fondamentale que vous devez vous poser est "Comment le DB sait-il quoi mettre là?" Une fois que vous décidez d'une méthode, la réponse devrait être simple, mais il n'y a pas de repas gratuits.

Mise à jour

Dans le passé, quand je devais faire quelque chose comme ça quand la connexion à la DB est avec un rôle d'application, la façon dont je l'ai fait est de créer une table temporaire et l'accès cette table à partir des procédures stockées. Les procédures actuellement stockées peuvent gérer les tables temporaires de cette manière, mais dans le passé, nous devions utiliser EXECUTE.

Il y a deux énormes limites à cette approche. Le premier est qu'il crée beaucoup de tables et cela mène éventuellement à la possibilité d'un wrapping d'oid.

De nos jours, je préfère de loin que les connexions à la base de données soient des connexions utilisateur. Cela rend ce beaucoup plus facile à gérer et vous pouvez simplement accéder via la valeur SESSION_USER (une erreur de débutant est d'utiliser CURRENT_USER qui vous montre le contexte actuel de sécurité plutôt que la connexion de l'utilisateur.

Aucune de ces approches fonctionnent bien avec Dans le premier cas, vous ne pouvez pas effectuer de regroupement de connexions car vos tables temporaires seront mal interprétées ou bousillées Dans la seconde, vous ne pouvez pas le faire parce que les rôles de connexion sont différents

Questions connexes