So würde Ihre Trigger-Funktion richtig funktionieren:
CREATE OR REPLACE FUNCTION loca_app.func_historico_mod_usuarios()
RETURNS trigger AS
$func$
BEGIN
EXECUTE format(
'INSERT INTO loca_app.tb_modificacoes
(mod_momento, mod_valor_anterior, mod_valor_atual, mod_usuario, mod_dado)
VALUES (now() , $1.%1$I , $2.%1$I , $3 , $4)
)', TG_ARGV[0])
USING OLD, NEW, TG_RELID
, (SELECT dad_id FROM loca_app.tb_dados
WHERE dad_nome = TG_ARGV[0] -- cast? see blow
LIMIT 1);
RETURN NULL; -- only good for AFTER trigger
END
$func$ LANGUAGE plpgsql;
Wichtige Punkte
-
Übergeben Sie die speziellen Zeilenwerte
OLDundNEWsowieTG_RELIDals Werte zuEXECUTEmit demUSINGKlausel. Möglicherweise müssen SieTG_RELIDwirken zu einem passenden Datentyp. Die Tabellendefinition vontb_modificacoesist nicht bekannt. Oder Sie wollen wirklich etwas anderes hier. Siehe unten.$1,$2und$3in der anEXECUTEübergebenen SQL-Zeichenfolge beziehen sich auf Ausdrücke inUSINGKlausel, nicht zu Funktionsparametern, die mit der gleichen Positionssyntax im Funktionskörper außen referenziert werden könnenEXECUTE. -
Verketten Sie Ihren dynamischen SQL-Befehl mit
format(). Viel sauberer und sicherer. Bezeichner in Anführungszeichen setzen und mit Escapezeichen versehen , Code und Werte richtig!%1$Iund%1$Lsind Formatbezeichner fürformat(). Lesen Sie das Handbuch für Details. -
Korrekte Groß-/Kleinschreibung erforderlich! Ihre Konvention, Bezeichner mit Großbuchstaben zu schreiben, ist in Oracle sinnvoll, wo Bezeichner ohne Anführungszeichen in Großbuchstaben umgewandelt werden. Es ist in Postgres nicht nützlich, wo stattdessen alles in Kleinbuchstaben gefaltet wird:
-
Verwenden Sie nicht
ILIKEinDAD_NOME ILIKE 'USU_NASCIMENTO'. Bei Postgres-Bezeichnern wird zwischen Groß- und Kleinschreibung unterschieden. Sie könnten haben mehrere übereinstimmende Werte indad_nome. Verwenden Sie=stattdessen und richtig geschriebene Bezeichner übergeben. Und stellen Sie sicher, dassdad_nomeeindeutig definiert ist. Siehe unten. -
Ihr Kommentar lautet:
MOD_USUARIO , -- Translated to: User (ID). Aber das ist nicht, was Sie passieren. Das Handbuch:Sie können
current_userverwenden odersession_userstattdessen: -
Sie können
LIMIT 1entfernen aus der Unterabfrage ifdad_nomeistUNIQUEdefiniert . Andernfalls müssen Sie entscheiden, welche Reihe Sie im Falle eines Gleichstands auswählen möchten - mitORDER BY. -
Triggerfunktionen sind erforderlich mit einem
RETURNabzuschließen Aussage. Könnte genauso gutRETURN NULLsein für einAFTERAbzug. Das Handbuch:
Verwandte:
- Wie übergibt man NEW.* an EXECUTE in der Trigger-Funktion
- Ersetzen Sie doppelte Anführungszeichen durch einfache Anführungszeichen in Postgres (plpgsql)
Nebenbei: Auch wenn Sie neu bei Postgres sind, sollten Sie diese Art von erweitertem dynamischem SQL vorsichtig verwenden. Sie müssen verstehen, was Sie tun.