Saya ingat telah mengangkat poin yang hampir sama ketika PG9 dalam kondisi alfa. Inilah jawaban dari Tom Lane (pengembang inti PG profil tinggi):
http://archives.postgresql.org/pgsql-general/2010-01/msg00221.php
Singkatnya:tidak akan diperbaiki.
Bukan untuk mengatakan bahwa saya setuju dengan saran Anda bahwa perilaku saat ini adalah bug. Lihatlah dari sudut yang berlawanan:ini adalah perilaku NOT DEFERRABLE
itu salah.
Faktanya, pelanggaran kendala dalam UPDATE ini seharusnya tidak pernah terjadi, karena pada akhir UPDATE kendala terpenuhi. Keadaan di akhir perintah adalah yang terpenting. Status perantara selama eksekusi satu pernyataan tidak boleh diekspos ke pengguna.
Sepertinya PostgreSQL mengimplementasikan batasan yang tidak dapat ditangguhkan dengan memeriksa duplikat setelah setiap baris diperbarui dan langsung gagal pada duplikat pertama, yang pada dasarnya cacat. Tapi ini adalah masalah yang diketahui, mungkin setua PostgreSQL. Saat ini solusi untuk ini justru menggunakan batasan DEFERRABLE. Dan ada beberapa ironi bahwa Anda melihatnya sebagai kekurangan karena gagal gagal, sementara entah bagaimana itu seharusnya menjadi solusi untuk kegagalan di tempat pertama!
Ringkasan status quo sejak PostgreSQL 9.1
-
NOT DEFERRABLE
UNIQUE
atauPRIMARY KEY
batasan diperiksa setelah setiap baris . -
DEFERRABLE
batasan diatur keIMMEDIATE
(INITIALLY IMMEDIATE
atau melaluiSET CONSTRAINTS
) dicentang setelah setiap pernyataan . -
DEFERRABLE
batasan disetel keDEFERRED
(INITIALLY DEFERRED
atau melaluiSET CONSTRAINTS
) dicentang setelah setiap transaksi .
Perhatikan perlakuan khusus UNIQUE
/ PRIMARY KEY
constraint. Mengutip halaman manual untuk CREATE TABLE
:
Batasan yang tidak dapat ditangguhkan akan segera diperiksa setelah setiap perintah .
Sementara itu menyatakan lebih jauh di Kompatibilitas bagian di bawah Non-deferred uniqueness constraints
:
Ketika
UNIQUE
atauPRIMARY KEY
batasan tidak dapat ditangguhkan, PostgreSQL segera memeriksa keunikan setiap kali baris dimasukkan atau dimodifikasi. Standar SQL mengatakan bahwa keunikan harus dipaksakan hanya di akhir pernyataan; ini membuat perbedaan ketika, misalnya, satu perintah memperbarui beberapa nilai kunci. Untuk mendapatkan perilaku yang sesuai standar, nyatakan batasan sebagaiDEFERRABLE
tetapi tidak ditangguhkan (yaitu,INITIALLY IMMEDIATE
). Ketahuilah bahwa ini bisa jauh lebih lambat daripada pemeriksaan keunikan langsung.
Penekanan saya yang berani.
Jika Anda membutuhkan FOREIGN KEY
batasan untuk mereferensikan kolom, DEFERRABLE
bukan pilihan karena (per dokumentasi):
Kolom yang direferensikan harus berupa kolom dari batasan kunci utama atau unik yang tidak dapat ditangguhkan dalam tabel yang direferensikan.