PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

Bagaimana cara meneruskan LAMA, BARU, dan pengidentifikasi ke EXECUTE dalam fungsi pemicu?

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 dan NEW serta TG_RELID sebagai nilai untuk EXECUTE dengan USING ayat. Anda mungkin harus mentransmisikan TG_RELID ke tipe data yang pas. Definisi tabel tb_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 ke EXECUTE lihat ekspresi di USING klausa, tidak ke parameter fungsi, yang dapat direferensikan dengan sintaks posisi yang sama di badan fungsi di luar EXECUTE .

  • 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 untuk format() . 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 di DAD_NOME ILIKE 'USU_NASCIMENTO' . Pengidentifikasi Postgres peka terhadap huruf besar-kecil. Anda bisa memiliki beberapa nilai yang cocok di dad_nome . Gunakan = sebagai gantinya dan berikan pengidentifikasi yang dieja dengan benar. Dan pastikan dad_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 atau session_user sebagai gantinya:

  • Anda dapat menghapus LIMIT 1 dari subquery if dad_nome didefinisikan UNIQUE . Jika tidak, Anda harus memutuskan baris mana yang akan dipilih jika seri - dengan ORDER BY .

  • Fungsi pemicu diperlukan untuk mengakhiri dengan RETURN penyataan. Mungkin juga RETURN NULL untuk AFTER pemicu. Manual:

Terkait:

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.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Postgresql 9.x:Indeks untuk mengoptimalkan kueri `xpath_exists` (XMLEXISTS)

  2. Python psycopg2 copy_from() untuk memuat data melempar kesalahan untuk nilai integer nol:DataError:sintaks input tidak valid untuk integer:

  3. Cara mempercepat kinerja penyisipan di PostgreSQL

  4. postgres ke MS Access

  5. Apa pro dan kontra melakukan perhitungan dalam sql vs. di aplikasi Anda?