Oracle PL/SQL बल्क संग्रह: FORALL उदाहरण

⚡ स्मार्ट सारांश

थोक संग्रह Oracle PL/SQL एक साथ कई पंक्तियों को एक संग्रह में लाता है, जबकि FORALL बड़ी मात्रा में DML डेटा को डेटाबेस में वापस भेजता है। दोनों ही SQL और PL/SQL इंजनों के बीच संदर्भ स्विच को कम करते हैं, जिससे प्रदर्शन बेहतर होता है।

  • 📦 थोक संग्रह: यह एक ही बार में कई पंक्तियों को एक संग्रह चर में लाता है, जिससे पंक्ति-दर-पंक्ति धीमी गति से पंक्तियों को लाने की प्रक्रिया बदल जाती है।
  • 🔁 सभी के लिए: यह एक ही कॉन्टेक्स्ट स्विच के साथ पूरे कलेक्शन में एक INSERT, UPDATE या DELETE ऑपरेशन चलाता है।
  • 📏 सीमा खंड: यह सीमा निर्धारित करती है कि प्रत्येक BULK COLLECT फ़ेच कितनी पंक्तियाँ लोड करता है, जिससे बड़ी तालिकाओं पर सत्र मेमोरी सुरक्षित रहती है।
  • 📊 बल्क कलेक्ट विशेषताएँ: %BULK_ROWCOUNT(n) विशेषता यह बताती है कि nवें FORALL DML स्टेटमेंट ने कितनी पंक्तियों को प्रभावित किया।
  • ⚙️ संग्रह की आवश्यकता है: INTO क्लॉज़ को किसी कलेक्शन प्रकार को लक्षित करना चाहिए, जैसे कि नेस्टेड टेबल या एसोसिएटिव ऐरे।
  • 🤖 एआई सहायता: GitHub Copilot जैसे AI सहायक BULK COLLECT और FORALL ब्लॉक तैयार करते हैं और LIMIT क्लॉज़ की अनुपस्थिति को चिह्नित करते हैं।

Oracle PL/SQL में BULK COLLECT और FORALL का LIMIT क्लॉज़ के साथ अवलोकन

बल्क कलेक्ट क्या है?

बल्क कलेक्ट, संदर्भ स्विच को कम करता है। एसक्यूएल और पीएल/एसक्यूएल इंजन की मदद से एसक्यूएल इंजन एक साथ कई रिकॉर्ड प्राप्त कर सकता है।

Oracle PL / SQL यह फ़ंक्शन रिकॉर्ड्स को एक-एक करके लाने के बजाय बल्क में लाने की सुविधा प्रदान करता है। इस BULK COLLECT फ़ंक्शन का उपयोग SELECT स्टेटमेंट में रिकॉर्ड्स को बल्क में भरने या किसी विशिष्ट डेटा को लाने के लिए किया जा सकता है। कर्सर बल्क में। चूंकि BULK COLLECT रिकॉर्ड्स को बल्क में फ़ेच करता है, इसलिए INTO क्लॉज़ में हमेशा एक कलेक्शन टाइप वेरिएबल होना चाहिए। BULK COLLECT का मुख्य लाभ यह है कि यह डेटाबेस और PL/SQL इंजन के बीच इंटरैक्शन को कम करके परफ़ॉर्मेंस को बढ़ाता है।

सिंटेक्स:

SELECT <column1> BULK COLLECT INTO bulk_variable FROM <table name>;
FETCH <cursor_name> BULK COLLECT INTO <bulk_variable>;

उपरोक्त सिंटैक्स में, BULK COLLECT का उपयोग SELECT और FETCH स्टेटमेंट से डेटा एकत्र करने के लिए किया जाता है।

FORALL क्लॉज

FORALL कथन निम्नलिखित कार्य करता है: डीएमएल संचालन यह बल्क डेटा पर काम करता है। यह FOR लूप स्टेटमेंट जैसा दिखता है, सिवाय इसके कि FOR लूप में क्रियाएं रिकॉर्ड स्तर पर होती हैं, जबकि FORALL में लूप की कोई अवधारणा नहीं है। इसके बजाय, दी गई सीमा में मौजूद संपूर्ण डेटा को एक ही समय में संसाधित किया जाता है।

सिंटेक्स:

FORALL <loop_variable> in <lower range> .. <higher range>

<DML operations>;

उपरोक्त सिंटैक्स में, दी गई डीएमएल प्रक्रिया लोअर और हायर रेंज के बीच मौजूद संपूर्ण डेटा पर लागू होगी।

सीमा खंड

बल्क कलेक्ट विधि संपूर्ण डेटा को एक ही बार में लक्ष्य संग्रह चर में लोड करती है, यानी पूरा डेटा एक ही बार में संग्रह चर में भर जाता है। लेकिन जब लोड किए जाने वाले रिकॉर्ड की कुल संख्या बहुत अधिक हो, तो यह विधि उचित नहीं है, क्योंकि PL/SQL संपूर्ण डेटा को लोड करने का प्रयास करते समय अधिक सेशन मेमोरी का उपयोग करता है। इसलिए, इस बल्क कलेक्ट ऑपरेशन के आकार को सीमित रखना हमेशा बेहतर होता है।

SELECT स्टेटमेंट में ROWNUM कंडीशन को शामिल करके इस आकार सीमा को आसानी से प्राप्त किया जा सकता है, जबकि कर्सर के मामले में यह संभव नहीं है।

इस पर काबू पाने के लिए, Oracle इसमें LIMIT क्लॉज़ दिया गया है जो उन रिकॉर्ड्स की संख्या को परिभाषित करता है जिन्हें बल्क में शामिल करने की आवश्यकता है।

सिंटेक्स:

FETCH <cursor_name> BULK COLLECT INTO <bulk_variable> LIMIT <size>;

उपरोक्त सिंटैक्स में, कर्सर फ़ेच स्टेटमेंट BULK COLLECT स्टेटमेंट के साथ-साथ LIMIT क्लॉज़ का उपयोग करता है।

बल्क कलेक्ट विशेषताएँ

कर्सर एट्रिब्यूट्स की तरह, BULK COLLECT में %BULK_ROWCOUNT(n) होता है जो FORALL स्टेटमेंट के nवें DML स्टेटमेंट में प्रभावित पंक्तियों की संख्या लौटाता है, यानी यह कलेक्शन वेरिएबल के प्रत्येक मान के लिए FORALL स्टेटमेंट में प्रभावित रिकॉर्ड की संख्या बताता है। 'n' शब्द कलेक्शन में उस मान के क्रम को दर्शाता है जिसके लिए पंक्ति गणना की आवश्यकता है।

उदाहरण 1: इस उदाहरण में, हम BULK COLLECT का उपयोग करके emp टेबल से सभी कर्मचारियों के नाम निकालेंगे, और हम FORALL का उपयोग करके सभी कर्मचारियों के वेतन में 5000 की वृद्धि भी करेंगे।

नीचे दिए गए स्क्रीनशॉट में BULK COLLECT और FORALL का यह उदाहरण और इसका आउटपुट दिखाया गया है। Oracle.

BULK COLLECT with LIMIT and FORALL उदाहरण में कर्मचारी वेतन को अपडेट करना Oracle PL / SQL

DECLARE
CURSOR guru99_det IS SELECT emp_name FROM emp;
TYPE lv_emp_name_tbl IS TABLE OF VARCHAR2(50);
lv_emp_name lv_emp_name_tbl;
BEGIN
OPEN guru99_det;
FETCH guru99_det BULK COLLECT INTO lv_emp_name LIMIT 5000;
FOR c_emp_name IN lv_emp_name.FIRST .. lv_emp_name.LAST
LOOP
Dbms_output.put_line('Employee Fetched:'||c_emp_name);
END LOOP;
FORALL i IN lv_emp_name.FIRST .. lv_emp_name.LAST
UPDATE emp SET salary=salary+5000 WHERE emp_name=lv_emp_name(i);
COMMIT;
Dbms_output.put_line('Salary Updated');
CLOSE guru99_det;
END;
/

उत्पादन

Employee Fetched:BBB
Employee Fetched:XXX
Employee Fetched:YYY
Salary Updated

Code स्पष्टीकरण:

  • Code पंक्ति 2: 'SELECT emp_name FROM emp' कथन के लिए कर्सर guru99_det घोषित करना।
  • Code पंक्ति 3: lv_emp_name_tbl को VARCHAR2(50) प्रकार की तालिका के रूप में घोषित करना।
  • Code पंक्ति 4: lv_emp_name को lv_emp_name_tbl प्रकार के रूप में घोषित करना।
  • Code पंक्ति 6: कर्सर खोलना.
  • Code पंक्ति 7: 5000 की सीमा आकार के साथ BULK COLLECT का उपयोग करके कर्सर को lv_emp_name वेरिएबल में लाया जा रहा है।
  • Code पंक्ति 8-11: lv_emp_name नामक संग्रह में मौजूद सभी रिकॉर्ड को प्रिंट करने के लिए एक FOR लूप स्थापित करना।
  • Code पंक्ति 12: FORALL फ़ंक्शन का उपयोग करके सभी कर्मचारियों के वेतन को 5000 से अपडेट करें।
  • Code पंक्ति 14: प्रतिबद्धता ट्रांजेक्शन.

अक्सर पूछे जाने वाले प्रश्न

नहीं। बल्क कलेक्ट सेलेक्ट में कभी भी NO_DATA_FOUND त्रुटि नहीं आती; इसके बजाय यह एक खाली कलेक्शन लौटाता है। हमेशा .COUNT विधि का उपयोग करके कलेक्शन की जांच करें।pingअन्यथा आप चुपचाप शून्य पंक्तियों को संसाधित कर सकते हैं।

SAVE EXCEPTIONS व्यक्तिगत पंक्तियों के विफल होने पर भी FORALL को चलते रहने देता है। विफल पंक्तियों को SQL%BULK_EXCEPTIONS में संग्रहीत किया जाता है, फिर Oracle इससे ORA-24381 त्रुटि उत्पन्न होती है, जिसे आप एक ट्रैप में डाल देते हैं। अपवाद प्रत्येक त्रुटि की जांच करने के लिए हैंडलर।

जब भी कोई लूप कई पंक्तियों को पढ़ता है तो BULK COLLECT का उपयोग करें। कर्सर FOR लूप प्रत्येक स्विच पर एक पंक्ति प्राप्त करता है, इसलिए बल्क फ़ेचिंग और FORALL का संयोजन बड़े परिणाम सेट पर कई गुना तेज़ी से चल सकता है।

BULK COLLECT एक साथ कई पंक्तियाँ लौटाता है, इसलिए इसे एक बहु-पंक्ति कंटेनर की आवश्यकता होती है। INTO लक्ष्य एक होना चाहिए। संग्रह जैसे कि नेस्टेड टेबल, VARRAY, या एसोसिएटिव ऐरे, न कि एक एकल स्केलर वेरिएबल।

नहीं। FORALL हेडर केवल एक INSERT, UPDATE, DELETE या MERGE ऑपरेशन को संचालित करता है। केवल इसके VALUES और WHERE क्लॉज़ में मौजूद मान ही प्रति पुनरावृति बदल सकते हैं। कई स्टेटमेंट के लिए, अलग-अलग FORALL स्टेटमेंट का उपयोग करें।

बल्क प्रोसेसिंग, रो-बाय-रो कोड की तुलना में कई गुना से लेकर सौ गुना से भी अधिक तेज हो सकती है, क्योंकि BULK COLLECT और FORALL हजारों इंजन कॉन्टेक्स्ट स्विच को कुछ ही में समेट देते हैं, जिससे बड़े डेटा वॉल्यूम पर ओवरहेड में भारी कमी आती है।

हां. गिटहब कोपिलॉट यह लेख एक टिप्पणी से BULK COLLECT फेच, FORALL DML लूप और LIMIT क्लॉज़ का मसौदा तैयार करता है, और संग्रह प्रकार की घोषणाओं का सुझाव देता है, हालांकि आपको बैच आकार और त्रुटि प्रबंधन की स्वयं समीक्षा करनी चाहिए।

एआई सहायक उन लूपों को स्कैन करते हैं जो एक बार में एक पंक्ति को फ़ेच या परिवर्तित करते हैं और उन्हें बल्क कलेक्ट, लिमिट और फ़ॉरऑल के साथ पुनः लिखने की अनुशंसा करते हैं। यह मशीन-लर्निंग समीक्षा उत्पादन से पहले ही लिमिट कैप की कमी और प्रदर्शन संबंधी बाधाओं को पकड़ लेती है।

इस पोस्ट को संक्षेप में इस प्रकार लिखें: