आप बैचों में क्यों कमिट करना चाहते हैं? यह केवल आपके प्रसंस्करण को धीमा करने वाला है। जब तक ऐसे अन्य सत्र नहीं हैं जो उन पंक्तियों को संशोधित करने का प्रयास कर रहे हैं जिन्हें आप हटाने का प्रयास कर रहे हैं, जो अन्य कारणों से समस्याग्रस्त लगता है, तो सबसे कुशल तरीका केवल एक ही DELETE के साथ डेटा को हटाना होगा, यानी
DELETE FROM uiv_response_income uri
WHERE EXISTS(
SELECT 1
FROM (<<bulk_delete_dup query>>) bdd
WHERE bdd.rowid = uri.rowid
)
बेशक, आपके कर्सर के पीछे की क्वेरी को कैसे डिज़ाइन किया गया है, इसके आधार पर इसे लिखने का एक अधिक इष्टतम तरीका हो सकता है।
यदि आप वास्तव में बल्क संग्रह को समाप्त करना चाहते हैं (जो प्रक्रिया को काफी धीमा कर देगा), तो आप DELETE करने के लिए WHERE CURRENT OF सिंटेक्स का उपयोग कर सकते हैं।
SQL> create table foo
2 as
3 select level col1
4 from dual
5 connect by level < 10000;
Table created.
SQL> ed
Wrote file afiedt.buf
1 declare
2 cursor c1 is select * from foo for update;
3 l_rowtype c1%rowtype;
4 begin
5 open c1;
6 loop
7 fetch c1 into l_rowtype;
8 exit when c1%notfound;
9 delete from foo where current of c1;
10 end loop;
11* end;
SQL> /
PL/SQL procedure successfully completed.
हालाँकि, जागरूक रहें कि चूंकि आपको पंक्ति को लॉक करना है (अद्यतन के लिए क्लॉज के साथ), आप लूप में कमिट नहीं डाल सकते। एक प्रतिबद्ध करने से आपके द्वारा अद्यतन के लिए अनुरोध किए गए ताले जारी हो जाएंगे और आपको एक ORA-01002 मिलेगा:अनुक्रम त्रुटि से बाहर निकलना
SQL> ed
Wrote file afiedt.buf
1 declare
2 cursor c1 is select * from foo for update;
3 l_rowtype c1%rowtype;
4 begin
5 open c1;
6 loop
7 fetch c1 into l_rowtype;
8 exit when c1%notfound;
9 delete from foo where current of c1;
10 commit;
11 end loop;
12* end;
SQL> /
declare
*
ERROR at line 1:
ORA-01002: fetch out of sequence
ORA-06512: at line 7
यदि आप लॉकिंग को हटाते हैं और कर्सर से प्राप्त किए गए मान (मानों) के आधार पर डेटा को हटाते हुए WHERE CURRENT OF सिंटैक्स से बचते हैं, तो आपको रनटाइम त्रुटि नहीं मिल सकती है। हालाँकि, यह अभी भी एक कमिटमेंट कर रहा है जो एक खराब अभ्यास है और मौलिक रूप से उन बाधाओं को बढ़ाता है जो आपको कम से कम रुक-रुक कर, ORA-01555:स्नैपशॉट बहुत पुरानी त्रुटि प्राप्त करेंगे। यह एकल SQL कथन या बल्क संग्रह विकल्प की तुलना में बहुत धीमा भी होगा।
SQL> ed
Wrote file afiedt.buf
1 declare
2 cursor c1 is select * from foo;
3 l_rowtype c1%rowtype;
4 begin
5 open c1;
6 loop
7 fetch c1 into l_rowtype;
8 exit when c1%notfound;
9 delete from foo where col1 = l_rowtype.col1;
10 commit;
11 end loop;
12* end;
SQL> /
PL/SQL procedure successfully completed.
बेशक, आपको यह भी सुनिश्चित करना होगा कि यदि आप पंक्तियों के कुछ सबसेट को संसाधित करते हैं और प्रक्रिया के मरने से पहले कुछ अज्ञात संख्या में अंतरिम कमिट करते हैं तो आपकी प्रक्रिया फिर से शुरू हो सकती है। अगर DELETE
पंक्ति आपके कर्सर से वापस नहीं आने के लिए पर्याप्त है, आपकी प्रक्रिया शायद पहले से ही पुनरारंभ करने योग्य है। लेकिन सामान्य तौर पर, अगर आप एक ही ऑपरेशन को कई लेन-देन में तोड़ने की कोशिश करते हैं तो यह एक चिंता का विषय है।