É assim que sua função de gatilho funcionaria corretamente:
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;
Pontos principais
-
Passe os valores de linha especiaisOLD
eNEW
bem comoTG_RELID
como valores paraEXECUTE
com oUSING
cláusula. Talvez seja necessário transmitirTG_RELID
para um tipo de dados adequado. A definição da tabela detb_modificacoes
não é divulgado. Ou você realmente quer outra coisa aqui. Veja abaixo.$1
,$2
e$3
na string SQL passada paraEXECUTE
consulte as expressões noUSING
cláusula, não para parâmetros de função, que podem ser referenciados com a mesma sintaxe posicional no corpo da função foraEXECUTE
.
-
Concatene seu comando SQL dinâmico usandoformat()
. Muito mais limpo e seguro. Cite e escape identificadores , código e valores devidamente!%1$I
e%1$L
são especificadores de formato paraformat()
. Leia o manual para obter detalhes.
-
Caso correto é necessário! Sua convenção para soletrar identificadores com letras maiúsculas faz sentido no Oracle, onde identificadores sem aspas são convertidos em letras maiúsculas. Não é útil no Postgres, onde tudo é dobrado para letras minúsculas:
-
Não useILIKE
emDAD_NOME ILIKE 'USU_NASCIMENTO'
. Os identificadores do Postgres diferenciam maiúsculas de minúsculas. Você poderia tem vários valores correspondentes emdad_nome
. Usar=
em vez disso e passar identificadores escritos corretamente. E certifique-se de quedad_nome
é definido como único. Veja abaixo.
-
Seu comentário diz:MOD_USUARIO , -- Translated to: User (ID)
. Mas não é isso que você passa. O manual:
Você pode querer usarcurrent_user
ousession_user
em vez de:
-
Você pode removerLIMIT 1
da subconsulta sedad_nome
é definido comoUNIQUE
. Caso contrário, você precisa decidir qual linha escolher em caso de empate - comORDER BY
.
-
As funções de gatilho são necessárias para terminar com umRETURN
declaração. Pode serRETURN NULL
para umAFTER
acionar. O manual:
Relacionado:
- Como passar NEW.* para EXECUTE na função trigger
- Substitua aspas duplas por aspas simples no Postgres (plpgsql)
Além: Embora você seja novo no Postgres, talvez queira usar esse tipo de SQL dinâmico avançado com cuidado. Você precisa entender o que está fazendo.