TRIGGER Problem beim DELETE in Audit-Tabelle

Folgendes Szenario:
In einer Audit Tabelle sollen die Aktionen Insert, Update und Delete protokolliert werden. Dazu soll jeder SQL-Funktion, die auf der Datenbank aufgerufen wird, der User mitgegeben werden. Dieser soll beim Insert, Update oder Delete in den jeweiligen Datensatz mitgeschrieben werden. Wenn ich als User1 also einen Insert mache, steht im entsprechenden Datensatz ‘User1’ als Changeuser und gleichzeitig wird in der Audit-Tabelle mit einem Trigger ein Datensatz angelegt.
Wenn User2 ein Update auf diesen Datensatz macht (update_function(1, “User2”)), ist er der neue Changeuser und das wird in der Audit-Tabelle mit dem Trigger protokolliert.
Problem: wenn ich ein DELETE auf diesen Datensatz mache, z.B. delete_function(1, “User3”), weil User3 den Datensatz 1 löscht, muss der User3 irgendwie “von aussen” in die Audit-Tabelle kommen. Denn im alten Datensatz steht nur User2. Ich kann also User3 mit .OLD nicht finden.
Frage: welche Möglichkeiten gibt es, diesen neuen User3, der gelöscht hat, in die Audit-Tabelle zu schreiben?

Vielen Dank im Voraus!

kannst Du das mit einem Beispiel zeigen? Kennst du die pg_audit-Extension?

Es geht dabei darum, im Trigger die Variable the_user zu füllen:

elsif (TG_OP = 'DELETE') then
    INSERT INTO audit(VALUE, VERSION, AUDIT_CHANGEDATE, AUDIT_CHANGEUSER, AUDIT_ACTION)
   VALUES(OLD.VALUE, OLD.VERSION + 1, OLD.CHANGEDATE, the_user, substring(TG_OP,1,1));

der aktuelle User ist current_user. Hilft das, oder verstehe ich Dein Problem nicht?

Sorry, da habe ich mich nicht klar genug ausgedrückt. current_user ist für alle User gleich, denn das ist der, der die Windows-Applikation startet und im Connection-String steht.
Es geht darum, den angemeldeten Windows-User zu übergeben.

das kannst Du aus der DB heraus nicht wirklich erkennen. Die DB sieht nur, woher die Verbindung kommt und mit welchem DB-User.

Ich habe mir überlegt mit einer Tabelle zu arbeiten, ich der ich den Windows-User ablege und dann zur Verfügung habe:

CREATE TEMPORARY TABLE tmp_vars( 
name varchar(64),
value varchar(64),
PRIMARY KEY (name)

Wäre das eine Möglichkeit?

wenn es deine Anforderungen erfüllt, was ich nicht beurteilen kann, dann ja.

Negativ: temp-table. Das bläht bei häufigem Gebrauch unnötig bestimmte Kataloge auf (ich hab da schon sehr grausame Sachen gesehen bei Kunden, die vit vielen Tenants arbeiten und das über separate Tabellen, Schemas, temp-Tabellen etc. gelöst haben.

Für triviale Sachen:

test=*# set session "myapp.user" = '12345';
SET
test=*# SELECT current_setting('myapp.user');
 current_setting 
-----------------
 12345
(1 row)
1 Like