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
OLD
undNEW
sowieTG_RELID
als Werte zuEXECUTE
mit demUSING
Klausel. Möglicherweise müssen SieTG_RELID
wirken zu einem passenden Datentyp. Die Tabellendefinition vontb_modificacoes
ist nicht bekannt. Oder Sie wollen wirklich etwas anderes hier. Siehe unten.$1
,$2
und$3
in der anEXECUTE
übergebenen SQL-Zeichenfolge beziehen sich auf Ausdrücke inUSING
Klausel, 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$I
und%1$L
sind 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
ILIKE
inDAD_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_nome
eindeutig 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_user
verwenden odersession_user
stattdessen: -
Sie können
LIMIT 1
entfernen aus der Unterabfrage ifdad_nome
istUNIQUE
definiert . Andernfalls müssen Sie entscheiden, welche Reihe Sie im Falle eines Gleichstands auswählen möchten - mitORDER BY
. -
Triggerfunktionen sind erforderlich mit einem
RETURN
abzuschließen Aussage. Könnte genauso gutRETURN NULL
sein für einAFTER
Abzug. 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.