Beginilah cara fungsi pemicu Anda bekerja dengan benar:
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;
Poin utama
-
Lewati nilai baris khusus
OLD
danNEW
sertaTG_RELID
sebagai nilai untukEXECUTE
denganUSING
ayat. Anda mungkin harus mentransmisikanTG_RELID
ke tipe data yang pas. Definisi tabeltb_modificacoes
tidak diungkapkan. Atau Anda benar-benar menginginkan sesuatu yang lain di sini. Lihat di bawah.$1
,$2
dan$3
dalam string SQL yang diteruskan keEXECUTE
lihat ekspresi diUSING
klausa, tidak ke parameter fungsi, yang dapat direferensikan dengan sintaks posisi yang sama di badan fungsi di luarEXECUTE
. -
Gabungkan perintah SQL dinamis Anda menggunakan
format()
. Jauh lebih bersih dan aman. Kutip dan lepas pengidentifikasi , kode dan nilai dengan baik!%1$I
dan%1$L
adalah penentu format untukformat()
. Baca manual untuk detailnya. -
Kasus yang benar diperlukan! Konvensi Anda untuk mengeja pengidentifikasi dengan huruf besar masuk akal di Oracle, di mana pengidentifikasi yang tidak dikutip diubah menjadi huruf besar. Ini tidak berguna di Postgres, di mana semuanya dilipat menjadi huruf kecil sebagai gantinya:
-
Jangan gunakan
ILIKE
diDAD_NOME ILIKE 'USU_NASCIMENTO'
. Pengidentifikasi Postgres peka terhadap huruf besar-kecil. Anda bisa memiliki beberapa nilai yang cocok didad_nome
. Gunakan=
sebagai gantinya dan berikan pengidentifikasi yang dieja dengan benar. Dan pastikandad_nome
didefinisikan unik. Lihat di bawah. -
Komentar Anda mengatakan:
MOD_USUARIO , -- Translated to: User (ID)
. Tapi bukan itu yang Anda lewati. Panduan:Anda mungkin ingin menggunakan
current_user
atausession_user
sebagai gantinya: -
Anda dapat menghapus
LIMIT 1
dari subquery ifdad_nome
didefinisikanUNIQUE
. Jika tidak, Anda harus memutuskan baris mana yang akan dipilih jika seri - denganORDER BY
. -
Fungsi pemicu diperlukan untuk mengakhiri dengan
RETURN
penyataan. Mungkin jugaRETURN NULL
untukAFTER
pemicu. Manual:
Terkait:
- Cara meneruskan NEW.* ke EXECUTE dalam fungsi pemicu
- Ganti tanda kutip ganda dengan tanda kutip tunggal di Postgres (plpgsql)
Selain: Meskipun Anda baru mengenal Postgres, Anda mungkin ingin menggunakan SQL dinamis tingkat lanjut semacam ini dengan hati-hati. Anda perlu memahami apa yang Anda lakukan.