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

Dalam fungsi pemicu, cara mendapatkan bidang mana yang diperbarui

Jika "sumber" tidak "mengirim pengenal", kolom tidak akan berubah. Maka Anda tidak dapat mendeteksi apakah UPDATE saat ini dilakukan oleh sumber yang sama dengan yang terakhir atau oleh sumber yang tidak mengubah kolom sama sekali. Dengan kata lain:ini tidak berfungsi dengan baik.

Jika "sumber" dapat diidentifikasi oleh fungsi informasi sesi apa pun, Anda dapat bekerja dengannya. Seperti:

NEW.column = session_user;

Tanpa syarat untuk setiap pembaruan.

Solusi Umum

Saya menemukan cara bagaimana memecahkan masalah aslinya. Kolom akan disetel ke nilai default di apa saja perbarui di mana kolomnya tidak diperbarui (bukan di SET daftar UPDATE ).

Elemen kunci adalah pemicu per kolom diperkenalkan di PostgreSQL 9.0 - pemicu khusus kolom menggunakan UPDATE OF column_name klausa.

Pemicu hanya akan diaktifkan jika setidaknya satu kolom yang terdaftar disebutkan sebagai target UPDATE perintah.

Itulah satu-satunya cara sederhana yang saya temukan untuk membedakan apakah kolom telah diperbarui dengan nilai baru yang identik dengan yang lama, atau tidak diperbarui sama sekali.

Satu bisa juga mengurai teks yang dikembalikan oleh current_query() . Tapi itu tampaknya rumit dan tidak dapat diandalkan.

Fungsi pemicu

Saya menganggap kolom col didefinisikan NOT NULL .

Langkah 1: Setel col ke NULL jika tidak berubah:

CREATE OR REPLACE FUNCTION trg_tbl_upbef_step1()
  RETURNS trigger AS
$func$
BEGIN
   IF OLD.col = NEW.col THEN
      NEW.col := NULL;      -- "impossible" value
   END IF;

   RETURN NEW;
END
$func$  LANGUAGE plpgsql;

Langkah 2: Kembali ke nilai lama. Pemicu hanya akan diaktifkan, jika nilainya benar-benar diperbarui (lihat di bawah):

CREATE OR REPLACE FUNCTION trg_tbl_upbef_step2()
  RETURNS trigger AS
$func$
BEGIN
   IF NEW.col IS NULL THEN
      NEW.col := OLD.col;
   END IF;

   RETURN NEW;
END
$func$  LANGUAGE plpgsql;

Langkah 3: Sekarang kita dapat mengidentifikasi pembaruan yang kurang dan menetapkan nilai default sebagai gantinya:

CREATE OR REPLACE FUNCTION trg_tbl_upbef_step3()
  RETURNS trigger AS
$func$
BEGIN
   IF NEW.col IS NULL THEN
      NEW.col := 'default value';
   END IF;

   RETURN NEW;
END
$func$  LANGUAGE plpgsql;

Pemicu

Pemicu untuk Langkah 2 ditembakkan per kolom!

CREATE TRIGGER upbef_step1
  BEFORE UPDATE ON tbl
  FOR EACH ROW
  EXECUTE PROCEDURE trg_tbl_upbef_step1();

CREATE TRIGGER upbef_step2
  BEFORE UPDATE OF col ON tbl                -- key element!
  FOR EACH ROW
  EXECUTE PROCEDURE trg_tbl_upbef_step2();

CREATE TRIGGER upbef_step3
  BEFORE UPDATE ON tbl
  FOR EACH ROW
  EXECUTE PROCEDURE trg_tbl_upbef_step3();

Nama pemicu relevan, karena dijalankan dalam urutan abjad (semuanya BEFORE UPDATE )!

Prosedurnya dapat disederhanakan dengan sesuatu seperti "pemicu per-bukan-kolom" atau cara lain untuk memeriksa daftar target dari UPDATE dalam sebuah pemicu. Tapi saya tidak melihat pegangan untuk ini.

Jika col bisa NULL , gunakan nilai perantara "mustahil" lainnya dan periksa NULL tambahan dalam fungsi pemicu 1:

IF OLD.col IS NOT DISTINCT FROM NEW.col THEN
    NEW.col := '#impossible_value#';
END IF;

Sesuaikan sisanya.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Bagaimana cara membandingkan tanggal di bidang datetime di Postgresql?

  2. Cara menggunakan pernyataan yang disiapkan dengan Postgres

  3. Cara Mengaktifkan Log Kueri Lambat di PostgreSQL

  4. Cara Memeriksa Versi PostgreSQL Anda

  5. Tips Dan Trik Postgres