आप इसे एकल SQL कथन के साथ और अधिक कुशलता से कर सकते हैं डेटा-संशोधित सीटीई के साथमजबूत> .
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 यहां
(पृष्ठ 11)
SQL Fiddle
(पृष्ठ 9.6)
यह बहुतहोना चाहिए तेज और क्लीनर। लूपिंग तुलनात्मक रूप से महंगा है, अपवाद प्रबंधन तुलनात्मक रूप से और भी अधिक महंगा है।
अधिक महत्वपूर्ण बात, lab
में संदर्भ cpt
. में संबंधित मास्टर रो पर रीडायरेक्ट किया जाता है स्वचालित रूप से, जो अभी तक आपके मूल कोड में नहीं था। तो आप एक ही बार में सभी धोखेबाज़ों को हटा सकते हैं ।
यदि आप चाहें तो आप इसे अभी भी plpgsql या SQL फ़ंक्शन में लपेट सकते हैं।
स्पष्टीकरण
-
पहले सीटीई में
plan
, समानcdesc
. के साथ प्रत्येक विभाजन में एक मास्टर पंक्ति की पहचान करें . आपके मामले में न्यूनतमrecid
. के साथ पंक्ति । -
दूसरे सीटीई में
upd_lab
cpt
. में डुप्ली को मास्टर पंक्ति में संदर्भित करने वाली सभी पंक्तियों को पुनर्निर्देशित करें । -
अंत में, डुप्लिकेट हटाएं, जो अपवाद नहीं उठाने वाला है क्योंकि निर्भर पंक्तियों को एक ही समय में शेष मास्टर पंक्ति से जोड़ा जा रहा है।
ON DELETE RESTRICT
सभी सीटीई और एक बयान . की मुख्य क्वेरी वस्तुतः समवर्ती रूप से . अंतर्निहित तालिकाओं के एक ही स्नैपशॉट पर कार्य करते हैं . वे अंतर्निहित तालिकाओं पर एक दूसरे के प्रभाव को नहीं देखते हैं:
ON DELETE RESTRICT
. के साथ FK बाधा की अपेक्षा की जा सकती है अपवादों को उठाने के लिए, क्योंकि [प्रति दस्तावेज़ीकरण] [3]:
हालाँकि, उपरोक्त कथन एक एकल आदेश है और, [मैनुअल फिर से] [3]:
बोल्ड जोर मेरा। कम प्रतिबंधात्मक डिफ़ॉल्ट के लिए काम करता है ON DELETE NO ACTION
भी, बिल्कुल।
लेकिन एक ही टेबल पर लिखने वाले समवर्ती लेनदेन से सावधान रहें, लेकिन यह एक सामान्य विचार है, इस कार्य के लिए विशिष्ट नहीं है।
UNIQUE
. के लिए एक अपवाद लागू होता है और PRIMARY KEY
बाधा, लेकिन यह इस से संबंधित नहीं है मामला: