Ето как вашата тригерна функция ще работи правилно:
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;
Основни точки
-
Предайте стойностите на специалния ред
OLD
иNEW
както иTG_RELID
като стойности заEXECUTE
сUSING
клауза. Може да се наложи да изпълнитеTG_RELID
към подходящ тип данни. Дефиницията на таблицата наtb_modificacoes
е неразкрит. Или наистина искате нещо друго тук. Вижте по-долу.$1
,$2
и$3
в SQL низа, предаден наEXECUTE
препраща към изразите вUSING
клауза, не към функционални параметри, които могат да бъдат посочени със същия позиционен синтаксис в тялото на функцията външноEXECUTE
. -
Свържете вашата динамична SQL команда, като използвате
format()
. Много по-чист и безопасен. Цитиране и екраниране на идентификатори , код и стойности правилно!%1$I
и%1$L
са спецификатори на формат заformat()
. Прочетете ръководството за подробности. -
Изисква се правилен регистър! Вашата конвенция за изписване на идентификатори с главни букви има смисъл в Oracle, където идентификаторите без кавички се преобразуват в главни букви. Не е полезно в Postgres, където вместо това всичко е сгънато в малки букви:
-
Не използвайте
ILIKE
вDAD_NOME ILIKE 'USU_NASCIMENTO'
. Идентификаторите на Postgres са чувствителни към главни и малки букви. Вие можете имат множество съответстващи стойности вdad_nome
. Използвайте=
вместо това и подавайте идентификатори, изписани правилно. И се уверете, чеdad_nome
се определя уникално. Вижте по-долу. -
Вашият коментар гласи:
MOD_USUARIO , -- Translated to: User (ID)
. Но това не е това, което преминавате. Ръководството:Може да искате да използвате
current_user
илиsession_user
вместо това: -
Можете да премахнете
LIMIT 1
от подзаявката ifdad_nome
е дефинираноUNIQUE
. В противен случай трябва да решите кой ред да изберете в случай на равенство - сORDER BY
. -
Функциите за задействане са задължителни за прекратяване с
RETURN
изявление. Може също да еRETURN NULL
заAFTER
спусък. Ръководството:
Свързани:
- Как да подадете NEW.* към EXECUTE във функция за задействане
- Заменете двойните кавички с единични кавички в Postgres (plpgsql)
Настрани: Докато сте нови в Postgres, може да искате да използвате този вид усъвършенстван динамичен SQL внимателно. Трябва да разбирате какво правите.