Theory
Overdue-List की सैर
कल्पना कीजिए आपकी university librarian आपको कागज़ की एक sheet देती है जिसमें 45 students के नाम हैं जिन्होंने अपनी programming textbooks नहीं लौटाईं। आपका काम पहला नाम देखना, उनका phone number खोजना, एक warning note print करना, उन्हें काटना, और अगली row पर सरकना है। आप इस sequence को हाथ से दोहराते हैं जब तक rows ख़त्म न हो जाएँ। PL/SQL में, अगर एक query कई records return करती है, computer उन सबको एक अकेली झलक में एक साथ process नहीं कर सकता। हमें database engine को इन बिल्कुल physical steps से स्पष्ट रूप से guide करना होगा: data की ओर point करना, इसे load करना, एक बार में एक line पकड़ना, और workspace साफ़ करना।
Theory
Underground Water Pipeline
एक explicit cursor manage करने को एक farm पर एक agricultural borewell pipeline set up करने की तरह सोचिए। पहले, आप blueprint बिछाते हैं जो बिल्कुल map करता है कि underground water channel कहाँ चलता है (DECLARE)। अगला, आप main valve खोलते हैं, पानी को आपके local holding tank में ऊपर उमड़ाते हुए (OPEN)। फिर, आप अपनी crops को क्रमिक रूप से पानी देने के लिए tap से अपनी buckets एक-एक करके भरते हैं (FETCH)। आख़िर में, जब fields पूरी तरह पानी में आ जाते हैं, आप बिजली बचाने और system flooding रोकने के लिए valve को कसकर बंद करते हैं (CLOSE)।
Theory
Explicit Control के चार आदेश
multi-row outputs को एक TOO_MANY_ROWS exception के साथ अपने code को crash किए बिना सुरक्षित रूप से सँभालने के लिए, आपको cursor के life cycle का पूर्ण programmatic स्वामित्व लेना होगा। यह lifecycle आपके PL/SQL block structure में लिखे चार अलग operational commands में टूटा है।
At a glance
एक programmer-managed explicit cursor की व्यवस्थित संरचनात्मक यात्रा।
| Lifecycle Phase | PL/SQL Keyword | Server Level पर क्या होता है | Memory & Pointer State |
|---|---|---|---|
| 1. Allocation | DECLARE | एक named cursor handle को एक ख़ास, static SELECT statement blueprint से जोड़ता है। | अभी तक कोई database rows fetch नहीं होतीं; केवल SQL syntax structure compile होता है। |
| 2. Execution | OPEN | query execute करता है, RAM में private Active Set populate करता है, और pre-first row की ओर point करता है। | Memory buffers data lock करते हैं; system pointer row number 1 के ठीक ऊपर मँडराता है। |
| 3. Extraction | FETCH | active row से column values को local variables में copy करता है और pointer आगे बढ़ाता है। | मौजूदा record data process होता है; pointer बिल्कुल एक row step नीचे सरकता है। |
| 4. Reclamation | CLOSE | cursor deactivate करता है, बची records RAM से flush करता है, और pointer नष्ट करता है। | active set context memory स्थायी रूप से वापस database engine को मुक्त होती है। |
Practical
Library Overdue Ledger से गुज़रना
-- An anonymous block to manually fetch and display high-fine library members
DECLARE
-- Step 1: Declare the cursor with its query blueprint
CURSOR c_fine_ledger IS
SELECT member_id, fine_balance
FROM members
WHERE fine_balance > 150;
-- Variables to receive cursor values during FETCH
v_mem_id members.member_id%TYPE;
v_balance members.fine_balance%TYPE;
BEGIN
-- Step 2: Open the data channel and freeze the active set
OPEN c_fine_ledger;
-- Iterating through rows explicitly
LOOP
-- Step 3: Pull data into target variables
FETCH c_fine_ledger INTO v_mem_id, v_balance;
-- Universal guard rule: exit early when no more rows exist
EXIT WHEN c_fine_ledger%NOTFOUND;
-- Operational logic on the current row
DBMS_OUTPUT.PUT_LINE('Alert sent to Member ID: ' || v_mem_id || ' | Penalty: Rs. ' || v_balance);
END LOOP;
-- Step 4: Shut down the valve and reclaim RAM
CLOSE c_fine_ledger;
END;
/Follow along
Tracer Bullet: Row Pointer की गति
- 1. OPEN Ignition query 3 मेल खाती rows पाती है। database engine इन 3 entries को रखता एक memory block बनाता है। pointer position 'Zero' पर, row 1 के ठीक ऊपर, टिकता है।
- 2. पहला FETCH Strike Oracle Row 1 पढ़ता है, इसका data 'v_mem_id' और 'v_balance' में copy करता है, और तुरंत pointer को नीचे Row 2 पर सीधे टिकने के लिए धकेलता है।
- 3. End-of-Data Signal चौथी loop iteration के दौरान, FETCH data पढ़ने की कोशिश करता है, पर pointer Row 3 के आगे ख़ाली space से टकराता है। internal system flag
%NOTFOUNDतुरंत FALSE से TRUE में पलटता है। - 4. Clean Evacuation
EXIT WHENrule TRUE flag पकड़ता है, तुरंत loop wheel से बाहर निकलता है, और 3-row memory cache purge करने के लिए control कोCLOSEstatement पर route करता है।
Quiz
क्या होता है अगर एक developer एक named explicit cursor पर इसके मेल खाते OPEN statement को execute करने से पहले एक FETCH statement execute करने की कोशिश करता है?
- block सफलतापूर्वक execute होता है पर सारे target variables NULL values से load होते हैं।
- Oracle execution की रक्षा के लिए अपने-आप पर्दे के पीछे cursor को implicitly open करता है।
- PL/SQL engine एक runtime crash से टकराता है एक तुरंत 'INVALID_CURSOR' (ORA-01001) exception फेंकते हुए।
- compiler compilation के दौरान sequence पकड़ता है और एक तुरंत syntax breakdown flag करता है।
Show the answer
PL/SQL engine एक runtime crash से टकराता है एक तुरंत 'INVALID_CURSOR' (ORA-01001) exception फेंकते हुए।
आप एक uninstalled pipeline से पानी नहीं खींच सकते! एक cursor से FETCH करने या CLOSE करने की कोशिश जो एक explicit OPEN command के ज़रिए initialize नहीं हुआ है 'INVALID_CURSOR' (Exception code ORA-01001) नामक एक runtime failure पैदा करती है।
Watch out
Infinite Duplication जाल
आप अपना EXIT WHEN safety valve कहाँ रखते हैं इस पर ध्यान दीजिए! practical exams में university students द्वारा की गई एक classic ग़लती exit condition को loop के अंदर FETCH statement से पहले रखना है। अगर आप किसी भी extraction से पहले loop की शुरुआत में ही %NOTFOUND जाँचते हैं, attribute FALSE (या NULL) evaluate होता है, यानी loop pass होगा। अंतिम दौर पर, यह बिल्कुल आख़िरी row का data दो बार print कर सकता है क्योंकि program data stream के सूख जाने का एहसास करने से पहले पुराने variables evaluate करता है!
Think first
Structural Variable Alignment जाँच
अगर आपका cursor SELECT statement बिल्कुल तीन columns निकालता है (जैसे id, name, fine), पर आपका FETCH code 'FETCH c1 INTO v_id, v_name;' बताता है, Oracle क्या करेगा? संरचनात्मक assignment symmetry के बारे में सोचिए।
Show the answer
compilation एक type mismatch या structural alignment error के साथ तुरंत crash होगी! Oracle सख़्ती से पूर्ण column-to-variable symmetry लागू करता है। अगर cursor query 3 columns return करती है, आपके FETCH block को उस data payload को सुरक्षित रूप से स्वीकार करने के लिए बिल्कुल 3 अलग local variables of matching, compatible data types देने होंगे।
Theory
Lab Exam Score Maximizer
जब एक external university laboratory examiner आपसे screen पर एक explicit cursor दिखाने को कहता है, हमेशा दोबारा जाँचिए कि आपका CLOSE command सुरक्षित रूप से loop body के बाहर बैठता है, पर block के अंतिम END; statement से ठीक पहले। cursors unclosed छोड़ना careless memory management आदतों के लिए performance marks खोने का सबसे आसान तरीक़ा है।
Summary
Key takeaways
- Explicit cursors custom, programmatic row-दर-row data pipelines हैं जो developers द्वारा हाथ से managed हैं।
- DECLARE step असल records track या row RAM allocate किए बिना target query blueprint set up करता है।
- OPEN step अंतर्निहित query चलाता है, active set context area बनाता है, और row pointer initialize करता है।
- FETCH step active record से data को local variables में खींचता है और pointer को नीचे आगे बढ़ाता है।
- CLOSE step pipeline को सुरक्षित रूप से समाप्त करता है, memory buffers वापस database engine को release करते हुए।
- %NOTFOUND attribute इस्तेमाल करके state changes track करने में विफल होना infinite loops या duplicate record printing में परिणत हो सकता है।
- Memory hook: इसे map करो (DECLARE), इसे switch on करो (OPEN), rows दुहो (FETCH), और valve सील करो (CLOSE)!