Hanya DEFERRABLE
kendala dapat ditangguhkan.
Izinkan saya menyarankan alternatif yang lebih baik terlebih dahulu:
1. INSERT
berurutan
Membalikkan urutan INSERT
pernyataan dan tidak ada yang perlu ditunda. Paling sederhana dan tercepat - jika memungkinkan.
2. Perintah tunggal
Lakukan dalam satu perintah . Maka masih tidak ada yang perlu ditunda, karena batasan yang tidak dapat ditangguhkan diperiksa setelah setiap perintah dan CTE dianggap sebagai bagian dari satu perintah:
WITH ins1 AS (
INSERT INTO b(j) VALUES(2)
)
INSERT INTO a(i) VALUES(2);
Saat melakukannya, Anda dapat menggunakan kembali nilai untuk INSERT
pertama; lebih aman / lebih nyaman untuk kasus tertentu atau sisipan multi-baris:
WITH ins1 AS (
INSERT INTO b(j) VALUES(3)
RETURNING j
)
INSERT INTO a(i)
SELECT j FROM ins1;
Tapi saya butuh batasan yang ditangguhkan! (Benarkah?)
ALTER TABLE b ADD CONSTRAINT fkey_ij FOREIGN KEY (j)
REFERENCES a (i) MATCH SIMPLE
ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE; -- !!!
Kemudian kode asli Anda bekerja (sedikit lebih lambat, karena kendala yang ditangguhkan menambah biaya).
db<>fiddle di sini
Terkait:
Jawaban asli saya mengutip manual :
Tapi itu menyesatkan karena hanya berlaku untuk "tindakan referensial", yaitu apa yang terjadi ON UPDATE
atau ON DELETE
ke baris dalam tabel yang direferensikan. Kasing yang ada bukan salah satunya - sebagai @zer0hedge ditunjukkan
.