Theory
Blind Dashboard
कल्पना कीजिए एक car चलाना जहाँ windshield पूरी तरह काला किया हुआ है, और आपको केवल radio पर दिए instructions से navigate करना है। अगर आप CampusLib database में overdue students के लिए fine balances update करते हैं, आप कैसे जानते हैं कि आपका SQL statement असल में 50 records बदला, 1 record modify किया, या बिल्कुल कुछ नहीं पाया? status feedback के बिना database operations चलाना अत्यधिक ख़तरनाक है। execution engine के अंदर सुरक्षित रूप से देखने के लिए, PL/SQL चार built-in system indicators देता है जिन्हें Cursor Attributes कहते हैं। वे dashboard status lights की तरह काम करते हैं, बिल्कुल उजागर करते हुए कि पिछले database transaction के दौरान क्या हुआ।
Theory
WhatsApp Read Receipt और Odometer
%FOUND और %NOTFOUND को WhatsApp delivery ticks की तरह सोचिए। जब आप एक fetch command execute करते हैं, %FOUND एक चमकीले नीले double-tick में बदल जाता है, साबित करते हुए कि आपके programmatic हाथ ने सफलतापूर्वक एक असली database row पकड़ा। अगर stream सूख जाती है और आप ख़ाली space पकड़ते हैं, इसके बजाय %NOTFOUND जल उठता है। इस बीच, %ROWCOUNT को एक car के trip meter (odometer) की तरह सोचिए। यह उस पल शून्य पर मरा शुरू होता है जब आप data valve खोलते हैं, और हर एक individual record row के लिए जो आपके loop filter से गुज़रता है tick-दर-tick (+1) ऊपर बढ़ता है।
Theory
चार System Monitors
PL/SQL किसी भी cursor action के लिए चार मूल properties track करता है। अगर आप हाथ से बनाए एक explicit cursor का निरीक्षण कर रहे हैं, आप इन tokens को सीधे अपने custom cursor handle से जोड़ते हैं (जैसे c_stud_cursor%FOUND)। अगर आप एक implicit statement जाँचना चाहते हैं, जैसे एक standard standalone UPDATE, DELETE, या single-row SELECT INTO, आप इन tokens को generic global prefix handle `SQL` के साथ जोड़ते हैं (जैसे SQL%ROWCOUNT)।
At a glance
PL/SQL cursor properties के लिए state matrix और datatype outcomes।
| Attribute | Data Type | Explicit Cursors के लिए Behavior | Implicit Cursors के लिए Behavior (SQL%) |
|---|---|---|---|
| %ISOPEN | BOOLEAN | TRUE evaluate होता है अगर cursor open और RAM में सक्रिय है; बंद होने पर FALSE। | हमेशा FALSE evaluate होता है क्योंकि Oracle execution के बाद implicit statements तुरंत ख़ुद बंद कर देता है। |
| %FOUND | BOOLEAN | TRUE return करता है अगर पिछले FETCH ने एक valid row खींची; कोई row fetch न होने पर FALSE; fetch करने से पहले NULL। | TRUE return करता है अगर एक INSERT/UPDATE/DELETE statement ने कम से कम एक row बदली, या एक SELECT INTO मेल खाया। |
| %NOTFOUND | BOOLEAN | TRUE return करता है अगर पिछला FETCH ख़ाली आया; एक row सफलतापूर्वक खींचने पर FALSE; fetch करने से पहले NULL। | TRUE return करता है अगर एक DML statement ने शून्य rows प्रभावित कीं, या एक SELECT INTO एक record खोजने में विफल रहा। |
| %ROWCOUNT | NUMBER | उस cursor stream से अब तक variables में fetch की rows की बिल्कुल कुल संचयी संख्या track करता है। | पिछले execution block द्वारा modify या delete की rows की कुल count तुरंत दिखाता है। |
Practical
Implicit और Explicit Status Hooks इस्तेमाल करके Rows का Audit
-- An anonymous block capturing execution metrics using system attributes
DECLARE
CURSOR c_defaulters IS
SELECT member_id FROM members WHERE fine_balance > 200;
v_id members.member_id%TYPE;
BEGIN
-- 1. Testing Implicit Attributes on a DML Update
UPDATE members
SET status = 'SUSPENDED'
WHERE fine_balance > 500;
IF SQL%FOUND THEN
DBMS_OUTPUT.PUT_LINE('Suspension applied! Rows impacted: ' || SQL%ROWCOUNT);
ELSE
DBMS_OUTPUT.PUT_LINE('No members crossed the high-fine threshold.');
END IF;
-- 2. Testing Explicit Attributes through a manual lifecycle
OPEN c_defaulters;
-- State Check right after opening
IF c_defaulters%ISOPEN THEN
DBMS_OUTPUT.PUT_LINE('Cursor open. Rows fetched so far: ' || c_defaulters%ROWCOUNT);
END IF;
LOOP
FETCH c_defaulters INTO v_id;
EXIT WHEN c_defaulters%NOTFOUND;
DBMS_OUTPUT.PUT_LINE('Processing item #' || c_defaulters%ROWCOUNT || ' for ID: ' || v_id);
END LOOP;
CLOSE c_defaulters;
END;
/Follow along
Explicit Attribute State Transitions की Timeline
- 1. OPEN से पहले %ISOPEN evaluate करना FALSE देता है। %FOUND, %NOTFOUND, या %ROWCOUNT call करने की कोशिश एक तुरंत ORA-01001 Invalid Cursor crash trigger करती है।
- 2. OPEN के तुरंत बाद %ISOPEN TRUE में पलटता है। %ROWCOUNT बिल्कुल 0 पढ़ता है। %FOUND और %NOTFOUND दोनों blank NULL states के रूप में report करते हैं।
- 3. सफल FETCH Cycles %FOUND TRUE evaluate होता है, %NOTFOUND FALSE बनता है, और variables में खींचे हर record के लिए %ROWCOUNT 1 से ऊपर tick करता है।
- 4. Stream Exhaustion pointer अंतिम row पार करता है। FETCH कुछ नहीं पाता। %FOUND FALSE में shift होता है, %NOTFOUND TRUE बनता है, और %ROWCOUNT अंतिम high score पर freeze होता है।
- 5. Post-CLOSE Purge %ISOPEN वापस FALSE में गिरता है। बाक़ी तीन properties तुरंत context खोते हैं और फिर से reference होने पर exceptions फेंकते हैं।
Quiz
एक explicit cursor open होने के तुरंत बाद, पर बिल्कुल पहला FETCH statement चलने से ठीक पहले 'c_cursor%ROWCOUNT' का ख़ास value क्या है?
- यह NULL return करता है क्योंकि अभी तक कोई extraction attempt शुरू नहीं हुआ।
- यह active set collection में इंतज़ार करती मेल खाती rows की कुल संख्या return करता है।
- यह 0 return करता है।
- Oracle एक ORA-01001 Invalid Cursor exception error state फेंकता है।
Show the answer
यह 0 return करता है।
एक cursor open करना engine set up करता है और पहली row के ठीक ऊपर point करता है, पर अभी तक कोई rows counter gate पार नहीं हुईं। इसलिए, %ROWCOUNT बिल्कुल 0 पढ़ता है। यह इस phase पर result set का कुल size पहले से calculate नहीं करता।
Watch out
Post-Close Memory Ghost जाल
यह university theory exams के लिए एक परम पसंदीदा चालाकी वाला सवाल है! students अक्सर इस तरह cleanup code लिखते हैं: CLOSE c1; IF c1%NOTFOUND THEN...। यह एक घातक logical जाल है! जिस बिल्कुल second आप CLOSE c1; execute करते हैं, private workspace memory से मिट जाता है और cursor identity नष्ट हो जाती है। एक बंद cursor से इसकी %NOTFOUND state पूछना आपको TRUE या FALSE नहीं देगा, यह तुरंत आपके पूरे program runtime को एक INVALID_CURSOR exception के साथ crash करता है!
Think first
Empty Implicit Update Evaluation जाँच
Mental Challenge: अगर आप एक UPDATE query execute करते हैं जो एक table में शून्य rows मिलाती है, 'SQL%NOTFOUND' और 'SQL%ROWCOUNT' किसमें evaluate होते हैं?
Show the answer
SQL%NOTFOUND TRUE evaluate होता है क्योंकि कोई database records आपके criteria से मेल नहीं खाए ताकि modification से गुज़रें। SQL%ROWCOUNT बिल्कुल 0 return करेगा, पुष्टि करते हुए कि disk पर शून्य mutations हुईं।
Theory
University Lab Exam Scoring रणनीति
external laboratory evaluations के लिए code लिखते समय, implicit statements evaluate करते समय कभी explicit cursor name prefix इस्तेमाल मत कीजिए। एक anonymous standalone UPDATE command के लिए IF c_my_cursor%FOUND लिखना एक तुरंत fail है। सारे standalone DML actions के लिए, evaluation panel से perfect performance marks की guarantee करने के लिए हमेशा सीधे prefix SQL% इस्तेमाल कीजिए।
Summary
Key takeaways
- Cursor attributes embedded status flags हैं जो सक्रिय statements के बारे में अहम operational metrics return करते हैं।
- मैनुअल pipelines के लिए explicit cursor name इस्तेमाल कीजिए, और implicit updates/deletes के लिए generic 'SQL' token।
- %ISOPEN active memory residency जाँचता है; implicit statements हमेशा FALSE हैं क्योंकि वे auto-terminate होते हैं।
- %FOUND और %NOTFOUND binary validation indicators हैं जो एक FETCH execute होने तक पूरी तरह NULL रहते हैं।
- %ROWCOUNT एक running tally है जो database द्वारा खींची या modify की rows की मात्रा track करता है।
- एक बंद explicit cursor पर attributes reference करना एक Invalid Cursor error के साथ execution context तुरंत तोड़ता है।
- Memory hook: %ISOPEN line जाँचता है, %FOUND data पकड़ता है, %NOTFOUND exit सँभालता है, और %ROWCOUNT ढेर गिनता है!