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
OLDdanNEWsertaTG_RELIDsebagai nilai untukEXECUTEdenganUSINGayat. Anda mungkin harus mentransmisikanTG_RELIDke tipe data yang pas. Definisi tabeltb_modificacoestidak diungkapkan. Atau Anda benar-benar menginginkan sesuatu yang lain di sini. Lihat di bawah.$1,$2dan$3dalam string SQL yang diteruskan keEXECUTElihat ekspresi diUSINGklausa, 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$Idan%1$Ladalah 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
ILIKEdiDAD_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_nomedidefinisikan 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_useratausession_usersebagai gantinya: -
Anda dapat menghapus
LIMIT 1dari subquery ifdad_nomedidefinisikanUNIQUE. Jika tidak, Anda harus memutuskan baris mana yang akan dipilih jika seri - denganORDER BY. -
Fungsi pemicu diperlukan untuk mengakhiri dengan
RETURNpenyataan. Mungkin jugaRETURN NULLuntukAFTERpemicu. 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.