Contoh Anda rusak. Sumber dan target sama di INSERT
di pemicu, yang pasti akan memunculkan pelanggaran unik setiap saat (kecuali saat memasukkan NULL) - ditekan oleh ON CONFLICT (test_name2) DO NOTHING
, jadi tidak ada yang terjadi di pemicunya.
Anda juga melupakan batasan unik di INSERT
asli Anda . Lihat di bawah.
INSERT INTO test2(test_name2)
VALUES(NEW.test_name2)
...
CREATE TRIGGER trigger_test
AFTER INSERT
ON test2
Mulailah dengan penyiapan yang tidak terlalu membingungkan:
CREATE TABLE test1 (col1 text UNIQUE);
CREATE TABLE test2 (col2 text UNIQUE);
Dan lebih efisien untuk memindahkan pg_trigger_depth()
ke pemicu itu sendiri. Jadi ini akan berhasil, menyalin baris yang dimasukkan ke test1
untuk test2
(dan bukan sebaliknya), hanya untuk pertama tingkat kedalaman pemicu:
CREATE OR REPLACE FUNCTION trig_test()
RETURNS trigger AS
$func$
BEGIN
INSERT INTO test2(col2) -- !!
VALUES (NEW.col1) -- !!
ON CONFLICT (col2) DO NOTHING; -- !!
RETURN NULL;
END
$func$ LANGUAGE plpgsql;
Saya menyimpannya sebagai AFTER
pemicu. Dapat berupa BEFORE
pemicu juga, tapi di sana Anda membutuhkan RETURN NEW;
.
CREATE TRIGGER trigger_test
AFTER INSERT ON test1 -- !!
FOR EACH ROW
WHEN (pg_trigger_depth() < 1) -- !!
EXECUTE PROCEDURE trig_test();
Mengapa (pg_trigger_depth() < 1)
?
Catatan bahwa Anda menjebak pelanggaran unik di test2
dengan cara ini (tidak ada yang terjadi), tetapi pelanggaran unik di test1
akan tetap memunculkan pengecualian kecuali Anda memiliki ON CONFLICT ... DO NOTHING
di sana juga. Tes Anda adalah angan-angan:
Harus:
INSERT INTO test1 values ('test') ON CONFLICT (col1) DO NOTHING;
Alternatif:Rantai dua INSERT
dengan CTE
Jika Anda memiliki kendali atas INSERT
perintah pada test1
, Anda dapat melakukan ini sebagai ganti pemicu:
WITH ins1 AS (
INSERT INTO test1(col1)
VALUES ('foo') -- your value goes here
ON CONFLICT (col1) DO NOTHING
RETURNING *
)
INSERT INTO test2(col2)
SELECT col1 FROM ins1
ON CONFLICT (col2) DO NOTHING;
Terkait:
- Sisipkan data dalam 3 tabel sekaligus menggunakan Postgres
- PostgreSQL multi INSERT. ..KEMBALI dengan beberapa kolom