Sie können format()
verwenden um das Erstellen einer dynamischen SQL-Abfrage viel einfacher zu machen, da sie automatisch korrekt mit Bezeichnern und Literalen umgeht. Eine Sache, die die Leute normalerweise übersehen, ist, dass Sie einen einzelnen Datensatzausdruck mit (...).*
auf alle seine Spalten erweitern können - das funktioniert auch für NEW
und OLD
Variablen in einem Trigger aufzeichnen, z.B. select (new).*
Sie können Variablen auch mit using
Schlüsselwort des execute
Aussage. Es besteht keine Notwendigkeit, den Datensatz zwischen einer Datensatz- und einer Textdarstellung hin und her zu konvertieren.
Mit dieser Möglichkeit kann Ihre Triggerfunktion vereinfacht werden zu:
DECLARE
l_sql text;
BEGIN
IF TG_TABLE_SCHEMA = 'public' THEN
newtable := TG_TABLE_NAME || '_actividad';
ELSE
newtable := TG_TABLE_SCHEMA || '_' || TG_TABLE_NAME || '_actividad';
END IF;
PERFORM creartablaactividad(TG_TABLE_SCHEMA, TG_TABLE_NAME);
l_sql := 'INSERT INTO actividad.%I SELECT current_user, current_timestamp, %L, ($1).*';
IF TG_OP = 'DELETE' THEN
execute format(l_sql, newtable, 'D') using OLD;
RETURN OLD;
ELSE
-- covers UPDATE and INSERT
execute format(l_sql, newtable, 'U') using NEW;
RETURN NEW;
END IF;
RETURN NULL; -- result is ignored since this is an AFTER trigger
END;
Verwendung von Platzhaltern wie %I
und %L
ermöglicht es auch, das eigentliche SQL nur einmal zu definieren und wiederzuverwenden. Diese "Parameter" werden durch das format()
ersetzt Funktion (die den $1
)
Beachten Sie die Verwendung von ($1).*
innerhalb der SQL-Zeichenfolge. Dadurch wird execute
-Anweisung erweitert den Datensatzparameter $1
zu allen seinen Spalten. Der Datensatz selbst wird "nativ" mit dem USING
übergeben Schlüsselwort.
Die Verwendung von INSERT
ohne Zielspaltenliste (insert into some_table ...
statt insert into some_table (col1, col2, ...) ...
) ist eine ziemlich zerbrechliche Sache. Wenn Quelle und Ziel nicht übereinstimmen, kann das Einfügen leicht fehlschlagen. .
Wenn Sie keine umfangreiche Berichterstellung für die Audit-Tabellen ausführen (wo explizite Spaltennamen viel effizienter wären), sollten Sie über einen allgemeineren Audit-Trigger mit einem JSON
nachdenken oder HSTORE
Spalte, um den gesamten Datensatz zu speichern. Es stehen mehrere vorgefertigte Audit-Trigger zur Verfügung:
- http://okbob.blogspot. de/2015/01/einfachste-umsetzung-der-geschichte.html
- https://github.com/wingspan/wingspan-auditing
- https://www.cybertec-postgresql.com /en/tracking-changes-in-postgresql/
- https://wiki.postgresql.org/wiki/Audit_trigger_91plus