Anda dapat melakukannya dengan lebih efisien dengan pernyataan SQL tunggal dengan CTE pengubah data .
WITH plan AS (
SELECT *
FROM (
SELECT recid, min(recid) OVER (PARTITION BY cdesc) AS master_recid
FROM cpt
) sub
WHERE recid <> master_recid -- ... <> self
)
, upd_lab AS (
UPDATE lab l
SET cpt_recid = p.master_recid -- link to master recid ...
FROM plan p
WHERE l.cpt_recid = p.recid
)
DELETE FROM cpt c
USING plan p
WHERE c.recid = p.recid
RETURNING c.recid;
db<>fiddle di sini
(hal 11)
SQL Fiddle
(hal 9.6)
Ini seharusnya banyak lebih cepat dan lebih bersih. Perulangan relatif mahal, penanganan pengecualian relatif lebih mahal.
Yang lebih penting, referensi di lab
diarahkan ke baris master masing-masing di cpt
secara otomatis, yang belum ada dalam kode asli Anda. Jadi Anda dapat menghapus semua penipuan sekaligus .
Anda masih dapat membungkusnya dalam fungsi plpgsql atau SQL jika Anda mau.
Penjelasan
-
Dalam
plan
CTE pertama , identifikasi baris master di setiap partisi dengancdesc
yang sama . Dalam kasus Anda, baris denganrecid
minimum . -
Di
upd_lab
CTE ke-2 redirect semua baris yang mereferensikan penipuan ke baris master dicpt
. -
Terakhir, hapus dupes, yang tidak akan memunculkan pengecualian karena baris yang bergantung ditautkan ke baris master yang tersisa secara virtual pada saat yang bersamaan.
ON DELETE RESTRICT
Semua CTE dan kueri utama dari pernyataan beroperasi pada snapshot yang sama dari tabel yang mendasarinya, hampir bersamaan . Mereka tidak melihat efek satu sama lain pada tabel yang mendasarinya:
Orang mungkin mengharapkan batasan FK dengan ON DELETE RESTRICT
untuk mengajukan pengecualian karena, [per dokumentasi][3]:
Namun, pernyataan di atas adalah satu perintah dan, [manual lagi][3]:
Penekanan saya yang berani. Berfungsi untuk ON DELETE NO ACTION
default yang tidak terlalu membatasi juga, tentu saja.
Namun berhati-hatilah terhadap transaksi bersamaan yang menulis ke tabel yang sama, tetapi itu adalah pertimbangan umum, tidak khusus untuk tugas ini.
Pengecualian berlaku untuk UNIQUE
dan PRIMARY KEY
kendala, tapi itu tidak menyangkut ini kasus: