Ecco come funzionerebbe correttamente la tua funzione di attivazione:
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;
Punti principali
-
Passa i valori di riga speciali
OLD
eNEW
così comeTG_RELID
come valori aEXECUTE
con ilUSING
clausola. Potrebbe essere necessario trasmettereTG_RELID
a un tipo di dati di adattamento. La definizione della tabella ditb_modificacoes
è sconosciuto. O vuoi davvero qualcos'altro qui. Vedi sotto.$1
,$2
e$3
nella stringa SQL passata aEXECUTE
fare riferimento alle espressioni inUSING
clausola, non ai parametri della funzione, a cui è possibile fare riferimento con la stessa sintassi posizionale nel corpo della funzione esternoEXECUTE
. -
Concatena il tuo comando SQL dinamico usando
format()
. Molto più pulito e sicuro. Cita ed esci da identificatori , codice e valori propriamente!%1$I
e%1$L
sono identificatori di formato performat()
. Leggi il manuale per i dettagli. -
È necessario il caso corretto! La tua convenzione per scrivere gli identificatori con lettere maiuscole ha senso in Oracle, dove gli identificatori senza virgolette vengono convertiti in lettere maiuscole. Non è utile in Postgres, dove invece tutto è piegato in minuscolo:
-
Non utilizzare
ILIKE
inDAD_NOME ILIKE 'USU_NASCIMENTO'
. Gli identificatori Postgres fanno distinzione tra maiuscole e minuscole. Potresti hanno più valori corrispondenti indad_nome
. Usa=
invece e passare gli identificatori scritti correttamente. E assicuratidad_nome
è definito unico. Vedi sotto. -
Il tuo commento dice:
MOD_USUARIO , -- Translated to: User (ID)
. Ma non è quello che passi. Il manuale:Potresti voler usare
current_user
osession_user
invece: -
Puoi rimuovere
LIMIT 1
dalla sottoquery sedad_nome
è definitoUNIQUE
. Altrimenti devi decidere quale riga scegliere in caso di parità - conORDER BY
. -
Le funzioni di attivazione sono richieste per terminare con un
RETURN
dichiarazione. Potrebbe anche essereRETURN NULL
per unAFTER
grilletto. Il manuale:
Correlati:
- Come passare NEW.* a EXECUTE nella funzione trigger
- Sostituisci le virgolette doppie con le virgolette singole in Postgres (plpgsql)
A parte: Anche se sei un nuovo utente di Postgres, potresti voler utilizzare con attenzione questo tipo di SQL dinamico avanzato. Devi capire cosa stai facendo.