Oto jak twoja funkcja wyzwalacza będzie działać poprawnie:
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;
Główne punkty
-
Przekaż specjalne wartości wierszy
OLD
iNEW
jak równieżTG_RELID
jako wartościEXECUTE
zUSING
klauzula. Być może będziesz musiał przesłaćTG_RELID
do typu danych dopasowania. Definicja tabelitb_modificacoes
jest nieujawniony. Albo naprawdę chcesz tutaj czegoś innego. Zobacz poniżej.$1
,$2
i$3
w ciągu SQL przekazanym doEXECUTE
odnoszą się do wyrażeń wUSING
klauzula, nie do parametrów funkcji, do których można się odwoływać za pomocą tej samej składni pozycyjnej w treści funkcji na zewnątrzEXECUTE
. -
Połącz swoje dynamiczne polecenie SQL za pomocą
format()
. O wiele czystszy i bezpieczniejszy. Cytuj i uciekaj identyfikatory , kod i wartości odpowiednio!%1$I
i%1$L
są specyfikatorami formatu dlaformat()
. Przeczytaj instrukcję, aby uzyskać szczegółowe informacje. -
Wymagana jest prawidłowa wielkość liter! Twoja konwencja pisowni identyfikatorów wielkimi literami ma sens w Oracle, gdzie niecytowane identyfikatory są konwertowane na duże litery. Nie jest to przydatne w Postgresie, gdzie wszystko składa się do małych liter:
-
Nie używaj
ILIKE
wDAD_NOME ILIKE 'USU_NASCIMENTO'
. W identyfikatorach Postgres rozróżniana jest wielkość liter. możesz mieć wiele pasujących wartości wdad_nome
. Użyj=
zamiast tego i przekaż poprawnie napisane identyfikatory. I upewnij się, żedad_nome
jest zdefiniowany jako unikalny. Zobacz poniżej. -
Twój komentarz brzmi:
MOD_USUARIO , -- Translated to: User (ID)
. Ale to nie jest to, co mijasz. Instrukcja:Możesz użyć
current_user
lubsession_user
zamiast tego: -
Możesz usunąć
LIMIT 1
z podzapytania, jeślidad_nome
jest zdefiniowanyUNIQUE
. W przeciwnym razie musisz zdecydować, który wiersz wybrać w przypadku remisu - za pomocąORDER BY
. -
Funkcje wyzwalania są wymagane zakończyć za pomocą
RETURN
oświadczenie. Równie dobrze może byćRETURN NULL
dlaAFTER
cyngiel. Podręcznik:
Powiązane:
- Jak przekazać NEW.* do EXECUTE w funkcji wyzwalacza
- Zamień podwójne cudzysłowy na pojedyncze cudzysłowy w Postgresie (plpgsql)
Na bok: Jeśli jesteś nowy w Postgresie, możesz chcieć ostrożnie używać tego rodzaju zaawansowanego dynamicznego SQL. Musisz zrozumieć, co robisz.