PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Wie speichere ich Daten mit Komma im Zeichen, die einen Trigger durchlaufen?

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: