Dit is hoe uw triggerfunctie correct zou werken:
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;
Belangrijkste punten
-
Geef de speciale rijwaarden door
OLD
enNEW
evenalsTG_RELID
als waarden omEXECUTE
met deUSING
clausule. Mogelijk moet jeTG_RELID
casten naar een passend gegevenstype. De tabeldefinitie vantb_modificacoes
is niet bekendgemaakt. Of je wilt hier echt iets anders. Zie hieronder.$1
,$2
en$3
in de SQL-string doorgegeven aanEXECUTE
verwijzen naar uitdrukkingen in deUSING
clausule, niet naar functieparameters, waarnaar kan worden verwezen met dezelfde positionele syntaxis in de functietekst buitenEXECUTE
. -
Voeg uw dynamische SQL-opdracht samen met
format()
. Veel schoner en veiliger. Citeer en ontsnap aan ID's , code en waarden naar behoren!%1$I
en%1$L
zijn formaatspecificaties voorformat()
. Lees de handleiding voor details. -
Juiste zaak is vereist! Uw conventie om identifiers met hoofdletters te spellen is logisch in Oracle, waar niet-geciteerde identifiers worden geconverteerd naar hoofdletters. Het is niet handig in Postgres, waar alles in plaats daarvan in kleine letters wordt gevouwen:
-
Gebruik
ILIKE
niet inDAD_NOME ILIKE 'USU_NASCIMENTO'
. Postgres-ID's zijn hoofdlettergevoelig. Je zou meerdere overeenkomende waarden hebben indad_nome
. Gebruik=
in plaats daarvan en geef identifiers correct gespeld door. En zorg ervoor datdad_nome
is uniek gedefinieerd. Zie hieronder. -
Uw commentaar zegt:
MOD_USUARIO , -- Translated to: User (ID)
. Maar dat is niet wat je passeert. De handleiding:Misschien wilt u
current_user
. gebruiken ofsession_user
in plaats daarvan: -
Je kunt
LIMIT 1
verwijderen uit de subquery alsdad_nome
is gedefinieerdUNIQUE
. Anders moet je beslissen welke rij je kiest in het geval van een gelijkspel - metORDER BY
. -
Triggerfuncties zijn vereist om te beëindigen met een
RETURN
uitspraak. Kan net zo goedRETURN NULL
zijn voor eenAFTER
trekker. De handleiding:
Gerelateerd:
- Hoe NIEUW.* door te geven aan UITVOEREN in de triggerfunctie
- Vervang dubbele aanhalingstekens door enkele aanhalingstekens in Postgres (plpgsql)
Terzijde: Hoewel Postgres nieuw voor u is, wilt u dit soort geavanceerde dynamische SQL misschien zorgvuldig gebruiken. Je moet begrijpen wat je doet.