इस post, में हम SQL Cursor के बारे में विस्तार से सीखेंगे। वास्तव में यह result set के प्रत्येक row को एक के बाद एक process करने में मदद करता है। चलिए हम इसे उदाहरण सहित सीखते है कि SQL Cursor कैसे कार्य करता है और यह क्यों उपयोगी है।


Cursor क्या होता है- What is Cursor in SQL in Hindi 

SQL में cursor एक विशेष database object है। इसका उपयोग एक रिजल्ट सेट से एक समय में एक row के डेटा को प्राप्त करने और उस पर कार्य करने के लिए किया जाता है।

यह एक pointer की भांति कार्य करता है जो query result के प्रत्येक row को पॉइंट करता है, ताकि आप एक-एक करके rows पर जा सकें।

जब आप प्रत्येक row पर जटिल कार्य जैसे values की जांच करना, condition के आधार पर update करना या एक-एक करके लॉजिक लागू करना आदि करते हैं तब यह उपयोगी है।

परंतु याद रहें कि cursors, सामान्य SQL queries की अपेक्षा धीमी और ज्यादा मेमोरी का उपयोग करता है।

अतः आपको cursor का उपयोग उसी समय करना चाहिए जब इसकी जरूरत है न की सरल कार्यों के लिए। 


Cursor की विशेषताएँ - Characteristics of Cursor in Hindi 

Cursor की निम्न विशेषताएँ है।
1) Cursors आपको एक query result से एक समय में एक row को प्राप्त करने और उसके साथ कार्य करने की देता है।
 
2) यह result set की हर पंक्ति तक पहुँचने के लिए pointer जैसा काम करता है।

3) आप cursor की मदद से हर row का डेटा पढ़ सकते हैं, बदल सकते हैं या हटा सकते हैं।

 4) विभिन्न प्रकार के cursors जैसे static, dynamic, forward-only, और scrollable होते है। ये data को विभिन्न तरीके से move करने में मदद करते हैं। 

5) जब आपको एक-एक करके लॉजिक लिखने की जरूरत होती है, तब Cursors का उपयोग अक्सर stored procedures के साथ किया जाता है 

6) Cursors, ज्यादा मेमोरी और प्रोसेसिंग पावर का उपयोग करता है अतः या सामान्य SQL queries की अपेक्षा धीमा है। 

7) आप SQL steps जैसे DECLARE, OPEN, FETCH, और CLOSE का उपयोग करके एक cursor को डिफाइन कर सकते हैं।

8) प्रत्येक row में जाने के दौरान cursor आपको Error की जांच करने और उन्हें संभालने में मदद करता है। 

9) ये result set को अस्थाई रूप से सुरक्षित करते हैं ताकि आप एक समय में एक row को process कर सके। 



Cursor का निर्माण करना ( Syntax और Example सहित

नीचे एक cursors का निर्माण और उसका उपयोग कैसे किया जाता है इसे उदाहरण के साथ अच्छे से समझाया गया है।


 Declare a Cursor(कर्सर को डिक्लेयर करना)

SQL में Cursor बनाने का पहला चरण होता है उसे DECLARE करना। एक cursor को निम्न प्रकार से Declare करते हैं। 

Syntax:
DECLARE cursor_name CURSOR FOR
SELECT * FROM table_name;

Example:
मान Employees` table के data को एक करके प्राप्त करना चाहते हैं।

DECLARE emp_cursor CURSOR FOR
SELECT * FROM Employees;

यह `emp_cursor` नाम से एक cursor को declare करता है जो `Employees` table से सभी rows और columns को select करता है।

यह एक बार में एक row से employee का data लेने के लिए तैयार रहता है।


Open Cursor Connection

Cursor को declare करने के बाद query को रन करने और result set को स्टोर करने के लिए हम OPEN statement का उपयोग करते हैं।

यह row को एक-एक करके लेने के लिए तैयार रहता है।

Syntax:
OPEN cursor_name;

Example:
OPEN emp_cursor;
यह emp_cursor नामक कर्सर को open करता है।


Fetch Data from the Cursor(कर्सर से डाटा प्राप्त करना) 

cursor, को open करने के बाद हम result set से एक समय में एक row प्राप्त करने के लिए FETCH का उपयोग करते है। 

प्रत्येक समय जब आप FETCH का उपयोग करते है तो यह अगले row को देता है।

SQL, data को access करने के लिए 6 methods का उपयोग करते है। 

FETCH Modeउपयोगसरल अर्थ 
NEXTFETCH NEXT FROM cursor_nameअगली row प्राप्त करें  (default)
PRIORFETCH PRIOR FROM cursor_nameपिछली row प्राप्त करता है
FIRSTFETCH FIRST FROM cursor_nameपहली row प्राप्त करता है
LASTFETCH LAST FROM cursor_nameअंतिम row प्राप्त करता है
ABSOLUTE nFETCH ABSOLUTE 3 FROM cursor_nameसीधे 3rd row प्राप्त करता है
RELATIVE nFETCH RELATIVE 2 FROM cursor_nameवर्तमान row के बाद की 2 rows प्राप्त करता 
RELATIVE -nFETCH RELATIVE -1 FROM cursor_nameवर्तमान row से पहले की 1 row लाता है
 

Syntax: 
FETCH NEXT FROM cursor_name INTO variable1, variable2, ...;

Example:
FETCH NEXT FROM emp_cursor INTO @EmployeeID, @EmployeeName, @EmployeeSalary;

यह SQL command  `emp_cursor` नामक cursor से अगले row को प्राप्त करता है। यह उस row की values को  `@EmployeeID`, `@EmployeeName`, और `@EmployeeSalary` variables में store करता है।


Close Cursor(कर्सर को क्लोज करना)

Close Cursor का उपयोग cursor द्वारा उपयोग किए जा रहे memory और system resources को free करने के लिए है। जब हम cursor का उपयोग data को प्राप्त करने के लिए कर चुके रहते है तब उसे अवश्य ही close कर देना चाहिए।

यह डेटाबेस को बेहतर तरीके और मेमोरी को बर्बाद होने जैसे समस्याओं से बचाता है। एक close किए गए cursor को फिर से उपयोग नहीं किया जा सकता जब तक उसे फिर से open न जाए। 

Syntax:
CLOSE cursor_name;

Example:
CLOSE emp_cursor;
`
ऊपर के उदाहरण में `emp_cursor` cursor का नाम है। जब employee data प्राप्त कर लिया जाता है तब cursor को close कर देते हैं।

ऊपर के सारे steps को एक साथ एक उदाहरण से समझते हैं।

Explanation

1) DELIMITER $$
 MySQL, बाय डिफॉल्ट प्रत्येक command को ; के साथ समाप्त कर देता है। जब हम एक cursor या procedure बनाते हैं तब उनके अंदर बहुत सारे ; का उपयोग करते हैं 

और हम नही चाहते कि MySQL गलती से पहले रुक जाएं। इसलिए हमें DELIMITER $$ से code को शुरू करना होता है।


2) CREATE PROCEDURE show_employees()
show_employees() नाम से आप एक नए procedure का निर्माण करते है।

3) BEGIN
यह procedure की body की शुरुआत है।

4) DECLARE done INT DEFAULT FALSE;

यह 'done' नाम से एक वेरिएबल को डिक्लेयर करता है। इसका उपयोग यह जांच करने के लिए होता है कि क्या डाटा समाप्त हो गया है।

शुरुआत में इसकी value `FALSE` false होती है जिसका मतलब डाटा अभी भी बचा हुआ है।

5) DECLARE emp_name VARCHAR(50);
यह एक employee के नाम की data को अस्थाई रूप से रखने के लिए `emp_name` से एक वेरिएबल बनाता है।

6) DECLARE emp_cursor CURSOR FOR  SELECT ename FROM employees;
यह emp_cursor से एक कर्सर का निर्माण करता है। यह ' employees` table से सभी employee names(ename) को fetch(प्राप्त करना) करता है।

7) DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
यदि और भी डाटा प्राप्त करने के लिए नहीं है तो set done = TRUE सेट करें। यह कहता है कि अब loop को रोकने का समय आ गया है।

8) OPEN emp_cursor;
यह cursor को खोलता है। अब यह एक के बाद एक row को पढ़ने के लिए शुरू होता है।

9) read_loop: LOOP
यह loop को शुरू करता है जो `read_loop` कहलाता है।
हम इस loop के अंदर एक समय में एक row को प्राप्त करेंगे।

10) FETCH emp_cursor INTO emp_name;
यह cursor से अगले row को प्राप्त करता है और employee के name को ' emp_name' में रखता है।

11) IF done THEN
  LEAVE read_loop;
END IF;
यदि और अधिक डाटा नहीं है (`done = TRUE`) तब loop से बाहर आए।

12) SELECT emp_name;
यह current employee के नाम को प्रिंट करता है। 

13) END LOOP;
यह loop को समाप्त करता है।

14) CLOSE emp_cursor;
जब loop का कार्य हो जाता है तब हम कर्सर को close कर देते हैं। यह एक अच्छी आदत है और मेमोरी को भी Free कर देता है।

15) END$$
यह procedure के अंत को बताता है।

16) DELIMITER ;
यह delimiter को वापस default `;` में reset कर देता है।
अब आप सामान्य SQL queries को फिर से लिख सकते हैं। 


Cursor को Call करना 

MySQL, में हम सीधे cursor को कॉल(रन ) नहीं कर सकते। हम stored procedure को call करते है जहां पर Cursor लिखा गया है ।

हमने ऊपर में Employees table पर show_employees procedure बनाया है। अतः emp_cursor को call करने के लिए हम निम्न प्रकार से show_employees को कॉल करते है।

cursor, Employees table से सभी employee के नामो को लेता है और loop का उपयोग करके एक समय में एक नाम को दिखाता है।


Cursor के प्रकार - Types of Cursor in SQL Hindi

कर्सर के निम्न प्रकार है।

Implicit Cursor

जब आप SELECT, INSERT, UPDATE, या DELETE query चलाते हैं तब SQL द्वारा स्वचालित रूप से implicit cursor का निर्माण किया जाता है। 

आपको इसे बनाने या नियंत्रण करने की जरूरत नहीं है। SQL, बैकग्राउंड में सब कुछ संभालता है। 

यह SQL को एक-एक करके rows पर कार्य करने में मदद करता है परंतु आप इसे explicit cursor के समान नहीं देख सकते।

इस प्रकार का cursor सरल होता है और by default अधिकांश queries में उपयोग किया जाता है। 

Implicit Cursor की उपयोगी विशेषताएं:

%FOUND: 
सत्य है यदि SQL operation, कम से कम एक row को प्रभावित करता है। 

%NOTFOUND: 
सत्य है यदि कोई rows प्रभावित नहीं किया जाता। 

%ROWCOUNT: 
प्रभावित होने वाले rows की संख्या को रिटर्न करता है।

%ISOPEN: 
जांच करता है कि क्या cursor open है।

Example
UPDATE employees
SET salary = salary + 1000
WHERE department = 'Sales';

यह query सभी Employees को salary में 1000 बढ़ाता है जिसका department, Sales है।


Explicit Cursor

SQL में explicit cursor एक user-defined cursor होता है, जो query के result को एक-एक करके प्रोसेस करने में मदद करता है। 

आपको इसे पहले `CURSOR` keyword का उपयोग करके डिक्लेअर करने और इसका उपयोग करने के लिए इसे open की जरूरत होती है।
 
उसके बाद आपको रिजल्ट में से प्रत्येक row को प्राप्त करना होता है ताकि आप उसे पर आवश्यक कार्य कर सके। 

जब सभी row process कर दिया जाता है तब आप cursor को close कर सकते है। Explicit cursors उस समय उपयोगी है जब आप एक stored procedure में कई rows को संभाल रहे होते हैं और आप उस पर पूरा नियंत्रण चाहते है। 

Example:

हमने नीचे Students table के लिए show_student_names नामक एक Procedure बनाया है जिसके अन्दर student_cursor नाम से एक कर्सर बनाया है।

सबसे पहले cursor को open किया जाता है। उसके बाद यह cursor एक समय में student के एक नाम को लेता है और उसे दिखाता है। 

जब table में और अधिक नाम नहीं रहते तब loop रुक जाता है और अंत में कर्सर को close कर दिया जाता है। 


MySQL में Cursor को Stored Procedure के अंदर नीचे दिए गए तरीके से Call किया जाता है। यह students के नामो को दिखाता है।



Cursor की आवश्यकता क्यों होती है? - Why We Need Cursors in SQL in Hindi 

जब हम डाटा को पंक्ति दर पंक्ति प्रोसेस करते हैं उस समय हमें SQL में cursors की जरूरत होती है। जो की सामान्य SQL queries में संभव नहीं है क्योंकि यह सभी rows पर एक साथ कार्य करता है। 

अतः हमें SQL में निम्न कारणों से Cursor  की जरूरत होती है।

1. Row-by-Row Processing
कभी-कभी हमें प्रत्येक row के साथ एक-एक करके कार्य करने की जरूरत होती है जैसे 
  • प्रत्येक row के लिए विशेष गणना करने के लिए
  • प्रत्येक यूजर को email भेजने के लिए
  •  प्रत्येक row के लिए विभिन्न कंडीशन की जांच करने के लिए।

2. Complex Logic
कुछ कार्य केवल SELECT, UPDATE, या DELETE query के द्वारा नहीं किए जा सकते। अतः Cursors, आपको कोड लिखने की अनुमति देता है
जो निम्न कार्य कर सकते हैं।
  • प्रति row कंडीशन की जांच करने के लिए
  •  प्रत्येक row के लिए क्या करना है यह निर्णय लेने के लिए।
  • यह आपको डाटा पर ज्यादा नियंत्रण देता है।

3. Set-Based Limitations
SQL, सेट आधारित ऑपरेशन के लिए बेहतर है, अर्थात जो एक साथ सभी rows को संभालता है परंतु यदि आपको निम्न कार्य करना है तो Cursor की जरूरत होती है।

  • Sequential processing (एक के बाद एक  ): 
  • प्रत्येक row पर एक के बाद एक काम करना।
  • प्रत्येक रो के लिए विभिन्न नियम या कार्य लागू करना।


Cursor के फायदे - Advantages of Cursor in Hindi 

Cursor के निम्न फायदे हैं
1) cursor आपको प्रत्येक row को अलग से handle करने देता है। 

2) custom logic के आधार पर प्रत्येक row के लिए चीजों को update, delete, या calculate कर सकते हैं। 

3) Cursors आपको conditions, loops, और decisions का उपयोग करने देता है जिसे सामान्य SQL के साथ करना कठिन है। 

4) stored procedures या scripts, के लिए Cursor आपको प्रत्येक record के लिए code को रन करने देता है। 

5) यदि आपके रिजल्ट में बहुत सारे rows हैं तब cursor बहुत सारे मेमोरी का उपयोग करने के बजाए छोटे भाग के साथ कार्य करने की अनुमति देता है।

6) आप प्रत्येक row के लिए errors को check और manage कर सकते हैं 



Disadvantages of Cursor in Hindi - Cursor के नुकसान

Cursor के निम्न नुकसान है।
1. Cursors, पंक्ति दर पंक्ति कार्य करता है जो की set आधारित SQL operations की अपेक्षा धीमा है। 

2. ये ज्यादा मेमोरी और सीपीयू का उपयोग करते हैं विशेष कर बड़े डाटा सेट के साथ। 

3. Cursor आधारित code को नियमित SQL की अपेक्षा लिखना, पढ़ना और debug करना कठिन है। 

4. Cursors लंबे समय के लिए rows या tables के locks को पकड़े रहता हैं जो अन्य उपयोगकर्ता को प्रभावित करता है। 

5. जब data का आकार बढ़ता है या एक समय में उसे कई users उपयोग करते हैं तब यह अच्छे से कार्य नहीं करता 

6. databases, एक समय में कई rows के साथ तेजी से कार्य करता है। Cursors, एक समय में एक row को संभालता है अतः यह धीमा है। 

7. Cursors, को अक्सर ज्यादा code लाइनों की जरूरत होती है, जिससे इसका रखरखाव और अपडेट कठिन हो जाता है।