Voici comment votre fonction de déclenchement fonctionnerait correctement :
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;
Points majeurs
-
Passez les valeurs de ligne spéciales
OLD
etNEW
ainsi queTG_RELID
en tant que valeurs pourEXECUTE
avec leUSING
clause. Vous devrez peut-être casterTG_RELID
à un type de données approprié. La définition de table detb_modificacoes
n'est pas divulgué. Ou vous voulez vraiment quelque chose d'autre ici. Voir ci-dessous.$1
,$2
et$3
dans la chaîne SQL passée àEXECUTE
faire référence aux expressions dans leUSING
clause, pas aux paramètres de fonction, qui peuvent être référencés avec la même syntaxe positionnelle dans le corps de la fonction outsideEXECUTE
. -
Concaténez votre commande SQL dynamique en utilisant
format()
. Beaucoup plus propre et plus sûr. Citez et échappez les identifiants , code et valeurs correctement!%1$I
et%1$L
sont des spécificateurs de format pourformat()
. Lire le manuel pour plus de détails. -
La casse correcte est requise ! Votre convention d'orthographe des identifiants avec des lettres majuscules est logique dans Oracle, où les identifiants sans guillemets sont convertis en lettres majuscules. Ce n'est pas utile dans Postgres, où tout est plié en minuscules :
-
N'utilisez pas
ILIKE
dansDAD_NOME ILIKE 'USU_NASCIMENTO'
. Les identifiants Postgres sont sensibles à la casse. Vous pourriez avoir plusieurs valeurs correspondantes dansdad_nome
. Utilisez=
à la place et transmettez les identifiants correctement orthographiés. Et assurez-vous quedad_nome
est défini unique. Voir ci-dessous. -
Votre commentaire dit :
MOD_USUARIO , -- Translated to: User (ID)
. Mais ce n'est pas ce que vous passez. Le manuel :Vous pouvez utiliser
current_user
ousession_user
à la place : -
Vous pouvez supprimer
LIMIT 1
de la sous-requête sidad_nome
est définiUNIQUE
. Sinon, vous devez décider quelle ligne choisir en cas d'égalité - avecORDER BY
. -
Les fonctions de déclenchement sont obligatoires se terminer par un
RETURN
déclaration. Pourrait tout aussi bien êtreRETURN NULL
pour unAFTER
gâchette. Le manuel :
Connexe :
- Comment passer NEW.* à EXECUTE dans la fonction de déclenchement
- Remplacez les guillemets doubles par des guillemets simples dans Postgres (plpgsql)
À part : Pendant que vous êtes nouveau sur Postgres, vous voudrez peut-être utiliser ce type de SQL dynamique avancé avec précaution. Vous devez comprendre ce que vous faites.