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

Bagaimana cara membuat PostgreSQL menyisipkan baris ke dalam tabel saat dihapus dari tabel lain?

Tulis fungsi pemicu. Sesuatu seperti ini:

CREATE OR REPLACE FUNCTION trg_backup_row()
  RETURNS trigger AS
$BODY$
BEGIN

INSERT INTO other_tbl
SELECT (OLD).*, t.other_col                -- all columns of from old table
-- SELECT OLD.col1, OLD.col2, t.other_col  -- alternative: some cols from old tbl
FROM   third_tbl t
WHERE  t.col = OLD.col  -- link to third table with info from deleted row
AND    <unique_condition_to_avoid_multiple_rows_if_needed>;

RETURN NULL;

END;
$BODY$
  LANGUAGE plpgsql VOLATILE;

Dan pemicu ON DELETE . Seperti ini:

CREATE TRIGGER delaft
  AFTER DELETE
  ON tbl
  FOR EACH ROW
  EXECUTE PROCEDURE trg_backup_row();

Elemen kunci

  • Sebaiknya jadikan pemicu AFTER DELETE dan FOR EACH ROW .

  • Untuk mengembalikan semua kolom dari tabel lama gunakan sintaks (OLD).* . Lihat manual tentang mengakses jenis komposit . Atau OLD.* adalah sintaks yang valid juga, karena OLD ditambahkan ke FROM klausa secara implisit. Untuk VALUES ekspresinya harus (OLD).* , meskipun. Seperti:

    INSERT INTO other_tbl
    VALUES((OLD).*, some_variable)
    
  • Anda dapat memasukkan nilai dari tabel lain seperti yang saya tunjukkan. Pastikan untuk mendapatkan satu baris, atau Anda membuat beberapa entri.

  • Saat pemicu memicu AFTER acara, fungsi dapat RETURN NULL .

Tentang visibilitas

Menanggapi komentar waspada @couling.

Sedangkan kunci asing dapat dideklarasikan sebagai DEFERRED , ini hanya akan menunda pemeriksaan integritas, bukan penghapusan itu sendiri. Baris yang dihapus di pemicu dieksekusi sebelum yang ada atau oleh ON DELETE CASCADE kunci asing tidak akan terlihat lagi pada saat ini AFTER DELETE pemicu disebut. (Semuanya jelas terjadi dalam satu transaksi. Tak satu pun dari detail ini penting untuk transaksi lain, yang akan melihat semua atau tidak ada efeknya. Lihat manual untuk lebih lanjut tentang Model MVCC dan isolasi transaksi .)

Oleh karena itu, jika Anda ingin memasukkan nilai dari baris tergantung sedemikian rupa di INSERT . Anda , pastikan untuk memanggil pemicu ini sebelum baris tersebut akan dihapus.

Anda mungkin harus membuat pemicu ini BEFORE DELETE .

Atau bisa juga berarti Anda harus mengurutkan pemicu yang sesuai, BEFORE pemicu datang sebelum AFTER pemicu, jelas. Dan pemicu pada tingkat yang sama dieksekusi dalam urutan abjad .

Namun, selama saya sangat tepat di sini, saya mungkin juga menambahkan bahwa perubahan yang dilakukan pada baris (atau baris tergantung) di BEFORE lain pemicu juga hanya terlihat jika dipanggil sebelum yang ini.

Saran saya buatlah AFTER pemicunya adalah karena kurang rentan terhadap komplikasi dan lebih murah jika pemicu lain dapat membatalkan (memutar kembali) DELETE setengah jalan melalui operasi - selama tidak ada hal di atas yang berlaku.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. DatabaseError:transaksi saat ini dibatalkan, perintah diabaikan hingga akhir blok transaksi?

  2. LAG() / LEAD() dari peringkat berikutnya (Postgresql)

  3. PostgreSQL memodifikasi bidang secara dinamis dalam catatan BARU dalam fungsi pemicu

  4. Dapatkan data 12 bulan terakhir dari Db dengan tahun di Postgres

  5. Mengutip nama kolom dengan NHibernate dan PostgreSQL