मुख्य सामग्री पर जाएँ

2026 में शीर्ष 20 PL/SQL इंटरव्यू प्रश्न और उत्तर

PL/SQL इंटरव्यू की तैयारी करें: फंक्शंस, ट्रिगर्स, डायनेमिक SQL, एरर हैंडलिंग, सर्वोत्तम प्रथाएँ, और वास्तविक-जीवन परिदृश्य-आधारित प्रश्न।
Allan Ouko
Allan Ouko

अपना निःशुल्क खाता बनाएँ

अभ्यास और ट्रैक अपनी प्रगति को।

Google के साथ जारी रखेंजारी रखकर, आप हमारी उपयोग की शर्तें, हमारी गोपनीयता नीति को स्वीकार करते हैं और यह भी कि आपका डेटा USA में संग्रहीत है।

PL/SQL, जो कि Oracle की SQL की प्रक्रियात्मक (procedural) भाषा एक्सटेंशन है, Oracle डेटाबेस के साथ काम करने पर अनिवार्य रूप से जानना चाहिए। यह डेटाबेस एडमिनिस्ट्रेटर, डेवलपर, और डेटा एनालिस्ट जैसे प्रमुख रोल्स पर लागू होता है, जिन्हें डेटाबेस के भीतर जटिल बिज़नेस लॉजिक संभालना पड़ता है।

मेरा मानना है कि इंटरव्यूअर उम्मीदवारों का आकलन तीन प्रमुख पहलुओं पर करते हैं:

  • सैद्धांतिक समझ: कोर सिद्धांत, डेटा प्रकार, नियंत्रण संरचनाएँ, और एक्सेप्शन हैंडलिंग।
  • व्यावहारिक कोडिंग क्षमता: कारगर स्टोर्ड प्रोसीजर, फंक्शंस, ट्रिगर्स, और पैकेज लिखना।
  • परफ़ॉर्मेंस विचार: निष्पादन समय सुधारने, संसाधन खपत घटाने, और SQL व PL/SQL के बीच अत्यधिक कॉन्टेक्स्ट स्विचिंग जैसी गलतियों से बचने के लिए PL/SQL कोड का अनुकूलन।

मदद के लिए, मैं PL/SQL इंटरव्यू प्रश्नों पर एक गाइड दे रहा/रही हूँ। मैं बुनियादी अवधारणाओं से शुरू करूँगा/करूँगी और आगे बढ़कर बल्क प्रोसेसिंग, डायनेमिक SQL, और परफ़ॉर्मेंस ट्यूनिंग जैसे उन्नत विषयों तक जाऊँगा/जाऊँगी।

यदि आप Oracle डेटाबेस की आधारभूत अवधारणाओं को समझना चाहते हैं, तो मैं हमारे Introduction to Oracle SQL कोर्स की सलाह देता/देती हूँ, जो बताता है कि Oracle के एक्ज़िक्यूशन इंजन में SQL और PL/SQL कैसे इंटरैक्ट करते हैं।

TL;DR 

  • PL/SQL, SQL के लिए Oracle का प्रक्रियात्मक एक्सटेंशन है, जो वेरिएबल्स, लूप्स, कंडीशनल्स, एक्सेप्शन हैंडलिंग, और प्रोसीजर, फंक्शंस, व पैकेज के माध्यम से मॉड्युलर कोड जोड़ता है
  • शुरुआती प्रश्न ब्लॉक संरचना (DECLARE, BEGIN, EXCEPTION, END), स्केलर/कम्पोज़िट/रेफ़रेंस डेटा टाइप्स, और कंट्रोल स्ट्रक्चर्स को कवर करते हैं
  • मध्यवर्ती प्रश्न स्टोर्ड प्रोसीजर बनाम फंक्शंस, पैकेज, ट्रिगर्स, एक्सेप्शन हैंडलिंग, और %NOTFOUND जैसे कर्सर एट्रिब्यूट्स को कवर करते हैं
  • उन्नत प्रश्न बल्क प्रोसेसिंग (BULK COLLECT, FORALL), EXECUTE IMMEDIATE के साथ डायनेमिक SQL, कम्पाउंड ट्रिगर्स, और PRAGMA डायरेक्टिव्स को कवर करते हैं
  • परिदृश्य-आधारित प्रश्न वास्तविक-जीवन कौशल परखते हैं: समवर्ती ट्रिगर डिज़ाइन, बैच ट्रांज़ैक्शन प्रोसेसिंग, पैकेज आर्किटेक्चर, और NOWAIT/SKIP LOCKED के साथ डेडलॉक रोकथाम

Beginner PL/SQL Interview Questions

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

1. PL/SQL क्या है?

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

व्यवहार में दोनों भाषाएँ कैसे अलग हैं, इसका सीधा तुलना देखें: हमारा Difference Between SQL and PL/SQL ट्यूटोरियल।

2. PL/SQL ब्लॉक की मूल संरचना क्या है?

PL/SQL ब्लॉक, PL/SQL में निष्पादन की बुनियादी इकाई है, और इसमें चार मुख्य सेक्शन होते हैं:

  • DECLARE (वैकल्पिक): वेरिएबल्स, कॉन्स्टेंट्स, कर्सर, और यूज़र-परिभाषित प्रकारों को परिभाषित करने के लिए।

  • BEGIN: निष्पादन योग्य सेक्शन जहां SQL क्वेरी और प्रक्रियात्मक स्टेटमेंट लिखे जाते हैं।

  • EXCEPTION (वैकल्पिक): रनटाइम त्रुटियों और एक्सेप्शंस को संभालता है ताकि त्रुटियों से शालीनता से उबरा जा सके।

  • END;: ब्लॉक का अंत दर्शाता है।

3. आवश्यक PL/SQL डेटा टाइप्स कौन-से हैं?

PL/SQL विभिन्न डेटा टाइप्स को सपोर्ट करता है, जो निम्न प्रकार से वर्गीकृत हैं:

  • स्केलर टाइप्स: एकल-मूल्य प्रकार जैसे NUMBER, VARCHAR2, DATE, BOOLEAN।

  • कम्पोज़िट टाइप्स: कलेक्शंस जैसे RECORD (कस्टम स्ट्रक्चर) और TABLE/VARRAY (एरेज़)।

  • रेफ़रेंस टाइप्स: डेटाबेस ऑब्जेक्ट्स के पॉइंटर्स, जैसे डायनेमिक क्वेरी प्रोसेसिंग के लिए REF CURSOR।

4. PL/SQL में बुनियादी कंट्रोल स्ट्रक्चर्स कौन-से हैं?

PL/SQL कई कंट्रोल स्ट्रक्चर्स प्रदान करता है जो प्रोग्राम के फ्लो को मैनेज करने में मदद करते हैं:

  • लूप्स: इसमें LOOP, FOR LOOP, और WHILE LOOP शामिल हैं, जो स्टेटमेंट्स का दोहरावपूर्वक निष्पादन करने देते हैं।

  • कंडीशनल स्टेटमेंट्स: इसमें IF और CASE स्टेटमेंट्स शामिल हैं, जो शर्तों के आधार पर अलग-अलग कोड ब्लॉक निष्पादित करते हैं। DECODE() फ़ंक्शन भी एक कंडीशनल का अच्छा उदाहरण है, जिसका अध्ययन करना उपयोगी है। 

Intermediate PL/SQL Interview Questions

बुनियादी प्रश्नों को कवर करने के बाद, अब कुछ मध्यवर्ती-स्तर के PL/SQL इंटरव्यू प्रश्नों पर चलते हैं। इस चरण में इंटरव्यूअर आपकी तकनीकी दक्षता परखते हैं कि आप PL/SQL अवधारणाओं को व्यवहार में कैसे लागू और उपयोग करते हैं।

5. स्टोर्ड प्रोसीजर और फंक्शंस में क्या अंतर है?

स्टोर्ड प्रोसीजर और फंक्शंस दोनों पुन: प्रयोज्य PL/SQL कोड ब्लॉक हैं, लेकिन उनका उद्देश्य अलग होता है।

स्टोर्ड प्रोसीजर ऐसे ऑपरेशन करने के लिए उपयोग होते हैं जो कोई मान (value) वापस नहीं करते, जैसे डेटा को जोड़ना, अपडेट करना, या हटाना। इन्हें ऐसे कार्यों के लिए उपयोग किया जाता है जो डेटा में परिवर्तन करते हैं या बिना परिणाम लौटाए जटिल ऑपरेशन करते हैं।

उदाहरण के लिए, नीचे दिया गया प्रोसीजर दिए गए employee_id के कर्मचारी का salary निर्दिष्ट p_increment जोड़कर अपडेट करता है ताकि इनपुट पैरामीटर्स के आधार पर सैलरी डायनेमिक रूप से अपडेट हो,

CREATE PROCEDURE update_salary(p_emp_id NUMBER, p_increment NUMBER) AS  
BEGIN  
    -- Update the salary of the employee with the given ID  
    UPDATE employees  
    SET salary = salary + p_increment  
    WHERE employee_id = p_emp_id;  
END;

दूसरी ओर, फंक्शंस ऑपरेशन करने के बाद कोई मान लौटाते हैं। ये ऐसे कैलकुलेशन या डेटा प्राप्ति के लिए उपयुक्त हैं जिन्हें परिणाम लौटाने की आवश्यकता होती है।

नीचे दिया गया फंक्शन किसी कर्मचारी की सैलरी प्राप्त करना सरल बनाता है, जिससे इसे SQL क्वेरी या अन्य प्रोसीजर्स में पुन: उपयोग किया जा सकता है।

CREATE FUNCTION get_employee_salary(p_emp_id NUMBER) RETURN NUMBER AS  
    v_salary NUMBER;  
BEGIN  
    -- Retrieve the salary for the given employee ID  
    SELECT salary INTO v_salary  
    FROM employees  
    WHERE employee_id = p_emp_id;  
    
    -- Return the retrieved salary  
    RETURN v_salary;  
END;
AttributeStored ProcedureFunction
Returns a valueNo (uses OUT parameters)Yes (single return value)
Usable in SQL queriesNoYes
Primary purposePerform an action (insert, update, delete)Compute and return a result
Called withEXEC procedure_name(...)SELECT function_name(...) FROM DUAL
Can have side effectsYesAvoid (breaks determinism)

हमारा User Defined Stored Procedures in SQL ट्यूटोरियल नामकरण मानक, पैरामीटर मोड्स, और वास्तविक जीवन के पैटर्न को विस्तार से कवर करता है।

6. PL/SQL पैकेज क्या हैं?

PL/SQL पैकेज संबंधित प्रोसीजर, फंक्शंस, और वेरिएबल्स के संग्रह होते हैं जो बेहतर संगठन और पुन: उपयोग के लिए कोड को एनकैप्सुलेट करते हैं। इनमें दो भाग होते हैं:

  • पैकेज स्पेसिफिकेशन: पब्लिक एलिमेंट्स (प्रोसीजर, फंक्शंस, वेरिएबल्स) घोषित करता है।
  • पैकेज बॉडी: स्पेसिफिकेशन में घोषित प्रोसीजर और फंक्शंस का इम्प्लीमेंटेशन समाहित करती है।

उदाहरण के लिए, नीचे दिया गया क्वेरी employee_pkg पैकेज बनाता है जो किसी कर्मचारी की सैलरी बढ़ाने के लिए एक प्रोसीजर और कुल कर्मचारियों की संख्या निकालने के लिए एक फंक्शन परिभाषित करता है, जिनका इम्प्लीमेंटेशन पैकेज बॉडी में दिया जाएगा।

-- Create a package named 'employee_pkg'
CREATE PACKAGE employee_pkg AS  

    -- Procedure to increase an employee's salary by a percentage  
    PROCEDURE raise_salary(p_emp_id NUMBER, p_percent NUMBER);  

    -- Function to return the total number of employees  
    FUNCTION get_total_employees RETURN NUMBER;  

END employee_pkg;

7. PL/SQL ट्रिगर्स क्या हैं?

ट्रिगर्स ऐसे PL/SQL ब्लॉक होते हैं जो विशिष्ट डेटाबेस घटनाओं, जैसे इन्सर्शन, अपडेट या डिलीशन के जवाब में स्वत: निष्पादित होते हैं। ट्रिगर्स का उपयोग बिज़नेस नियम लागू करने के लिए किया जाता है। इन्हें ऑडिटिंग के लिए भी आम तौर पर उपयोग किया जाता है। इन्हें निम्न प्रकार से वर्गीकृत किया जाता है:

  • रो-स्तरीय ट्रिगर्स: प्रत्येक प्रभावित पंक्ति के लिए एक बार निष्पादित होते हैं।
  • स्टेटमेंट-स्तरीय ट्रिगर्स: प्रभावित पंक्तियों की संख्या की परवाह किए बिना प्रति SQL स्टेटमेंट एक बार निष्पादित होते हैं।

नीचे दिया गया क्वेरी employees टेबल पर AFTER UPDATE ट्रिगर trg_salary_audit बनाता है, जो सैलरी में बदलावों को salary_audit table में लॉग करता है, जिसमें कर्मचारी ID, पुरानी और नई सैलरी, और अपडेट का टाइमस्टैम्प कैप्चर होता है।

-- Create or replace a trigger 'trg_salary_audit'
CREATE OR REPLACE TRIGGER trg_salary_audit  
AFTER UPDATE OF salary ON employees  -- Fires after salary updates in 'employees' table
FOR EACH ROW  -- Executes for each updated row
BEGIN  
    -- Inserts old and new salary details into 'salary_audit' table
    INSERT INTO salary_audit (employee_id, old_salary, new_salary, change_date)  
    VALUES (:OLD.employee_id, :OLD.salary, :NEW.salary, SYSDATE);  
END;

हमारा SQL Triggers ट्यूटोरियल पढ़ें ताकि इंटरव्यू में ट्रिगर्स का विषय आने पर आप तैयार रहें। 

एक ट्रिगर प्रकार जिसका अभी तक उल्लेख नहीं हुआ है वह है INSTEAD OF ट्रिगर। रो- और स्टेटमेंट-स्तरीय ट्रिगर्स से अलग, INSTEAD OF ट्रिगर्स किसी व्यू पर DML स्टेटमेंट के स्थान पर चलते हैं, जिससे आप आधारभूत बेस टेबल्स पर ऑपरेशन को संभालने वाला लॉजिक लिख सकते हैं। गैर-अपडेटेबल व्यूज़ को INSERT, UPDATE, और DELETE ऑपरेशंस स्वीकार कराने का यह मानक तरीका है।

-- Allow inserts into a non-updatable view of employees and departments
CREATE OR REPLACE TRIGGER trg_instead_of_insert
INSTEAD OF INSERT ON emp_dept_view
FOR EACH ROW
BEGIN
    INSERT INTO employees (employee_id, employee_name, department_id)
    VALUES (:NEW.employee_id, :NEW.employee_name, :NEW.department_id);
END;

8. PL/SQL में एक्सेप्शन हैंडलिंग के तरीके क्या हैं?

स्थिरता के लिए और क्रैश रोकने हेतु PL/SQL एरर-हैंडलिंग तंत्र प्रदान करता है। एक्सेप्शंस के प्रकार निम्नलिखित हैं:

  • प्रीडिफाइंड एक्सेप्शंस: बिल्ट-इन एक्सेप्शंस जैसे NO_DATA_FOUND, TOO_MANY_ROWS, और ZERO_DIVIDE।

  • यूज़र-परिभाषित एक्सेप्शंस: कस्टम एक्सेप्शंस को EXCEPTION से डिक्लेयर किया जाता है और RAISE से उठाया जाता है।

उदाहरण के लिए, निम्न PL/SQL ब्लॉक ID 100 वाले कर्मचारी की सैलरी प्राप्त करता है, यदि सैलरी 1000 से कम है तो एक कस्टम एक्सेप्शन उठाता है, और संभावित त्रुटियों को संभालता है, जिनमें कर्मचारी रिकॉर्ड का न मिलना और अप्रत्याशित एक्सेप्शंस शामिल हैं।

DECLARE  
    v_salary NUMBER;  -- Variable to store the employee's salary  
    e_low_salary EXCEPTION;  -- Custom exception for low salary  

BEGIN  
    -- Retrieve salary of employee with ID 100  
    SELECT salary INTO v_salary FROM employees WHERE employee_id = 100;  

    -- Raise exception if salary is below 1000  
    IF v_salary < 1000 THEN  
        RAISE e_low_salary;  
    END IF;  

EXCEPTION  
    WHEN NO_DATA_FOUND THEN  -- Handle case where employee ID is not found  
        DBMS_OUTPUT.PUT_LINE('Employee not found.');  
    WHEN e_low_salary THEN  -- Handle custom low salary exception  
        DBMS_OUTPUT.PUT_LINE('Salary is below the allowed threshold.');  
    WHEN OTHERS THEN  -- Handle any other unexpected errors  
        DBMS_OUTPUT.PUT_LINE('An unexpected error occurred: ' || SQLERRM);  

END;

एक्सेप्शन हैंडलिंग के सर्वोत्तम अभ्यास निम्नलिखित हैं:

  • हमेशा संभावित एक्सेप्शंस का अनुमान लगाएँ।
  • अर्थपूर्ण एरर संदेशों का उपयोग करें।
  • ऑडिटिंग के लिए एक्सेप्शंस को लॉग करें।
  • एक्सेप्शन हैंडलिंग कोड को संक्षिप्त रखें और रिकवरी पर केंद्रित करें।

9. आप कैसे सत्यापित करेंगे कि UPDATE स्टेटमेंट निष्पादित हुआ या नहीं?

SQL का %NOTFOUND एट्रिब्यूट यह निर्धारित करने के लिए उपयोग किया जा सकता है कि UPDATE स्टेटमेंट ने सफलतापूर्वक कोई रिकॉर्ड बदला है या नहीं। यदि अंतिम चले हुए SQL स्टेटमेंट ने किसी पंक्ति को प्रभावित नहीं किया, तो यह वेरिएबल TRUE लौटाता है।

उदाहरण के लिए, नीचे दिया गया क्वेरी विभाग 10 के कर्मचारियों की सैलरी में 10% की वृद्धि करके अपडेट करता है, और फिर %NOTFOUND एट्रिब्यूट का उपयोग करके जांचता है कि UPDATE स्टेटमेंट से कोई पंक्ति प्रभावित हुई या नहीं। यदि कोई पंक्ति अपडेट नहीं हुई, तो यह संदेश देता है, "No rows were updated." यदि पंक्तियाँ अपडेट हुईं, तो यह SQL%ROWCOUNT एट्रिब्यूट का उपयोग करके प्रभावित पंक्तियों की संख्या बताता है।

DECLARE
    -- Declare a variable to store the number of rows updated
    rows_updated INTEGER;
BEGIN
    -- Perform an UPDATE statement on the 'employees' table
    UPDATE employees
    SET salary = salary * 1.1
    WHERE department_id = 10;

    -- Check if any rows were updated by using %NOTFOUND
    IF SQL%NOTFOUND THEN
        -- If no rows were updated, print a message
        DBMS_OUTPUT.PUT_LINE('No rows were updated.');
    ELSE
        -- If rows were updated, print how many rows were affected
        rows_updated := SQL%ROWCOUNT;  -- Store the number of rows updated
        DBMS_OUTPUT.PUT_LINE(rows_updated || ' rows were updated.');
    END IF;
END;
/

Advanced PL/SQL Interview Questions

अब कुछ उन्नत इंटरव्यू प्रश्नों का अन्वेषण करते हैं, यदि आप ऐसी वरिष्ठ भूमिका के लिए आवेदन कर रहे हैं जिसमें अधिक अनुभव की आवश्यकता है।

10. PL/SQL में परफ़ॉर्मेंस ऑप्टिमाइज़ करने के तरीके क्या हैं?

PL/SQL परफ़ॉर्मेंस सुधार पाँच तकनीकों पर केंद्रित होता है।

  • बल्क प्रोसेसिंग (BULK COLLECT / FORALL): पंक्तियों को एक-एक कर के बजाय बैच में फ़ेच या मोडिफाई करें। Q11 में दोनों का व्यवहारिक उपयोग दिखाया गया है।
  • BULK COLLECT के साथ LIMIT क्लॉज़: प्रति बैच मेमोरी सीमित करने के लिए BULK COLLECT INTO v_coll LIMIT 500 उपयोग करें। बिना LIMIT के Oracle पूरा रिज़ल्ट सेट एक साथ मेमोरी में लोड करता है, जो बड़ी टेबल्स पर समस्या पैदा करता है।
  • NOCOPY हिंट: बड़े IN OUT पैरामीटर्स को बाय-रेफ़रेंस पास करें, बाय-वैल्यू नहीं। हर कॉल पर 50 MB कलेक्शन की डीप कॉपी महँगी है; NOCOPY इसे स्किप करता है।
  • नेटिव कम्पाइलेशन: सेशन या सिस्टम स्तर पर PLSQL_CODE_TYPE = NATIVE सेट करें। Oracle PL/SQL को बाइटकोड के बजाय मशीन कोड में कम्पाइल करता है, जिससे कम्प्यूट-हेवी रूटीन पर CPU समय घटता है।
  • RESULT_CACHE: इसे उन deterministic फंक्शंस पर जोड़ें जो समान इनपुट्स के साथ बार-बार कॉल होते हैं। Oracle फंक्शन बॉडी को पुन: निष्पादित किए बिना कैश्ड परिणाम लौटाता है।

PL/SQL ट्यूनिंग के पूरक SQL परफ़ॉर्मेंस तकनीकों का व्यापक दृष्टिकोण देखने के लिए, हमारा SQL Query Optimization गाइड देखें, जिसमें इंडेक्स डिज़ाइन और क्वेरी रीराइटिंग सहित 15 तकनीकें शामिल हैं।

11. कॉन्टेक्स्ट स्विचेस को न्यूनतम करने के लिए बल्क ऑपरेशंस का उपयोग कैसे करें?

PL/SQL, SQL-से-PL/SQL इंटरैक्शन को अनुकूलित करने के लिए बल्क प्रोसेसिंग तकनीकें प्रदान करता है, जिससे एक बार में कई पंक्तियाँ फ़ेच या मोडिफाई की जा सकें।

उदाहरण के लिए, निम्न PL/SQL ब्लॉक BULK COLLECT का उपयोग करके विभाग 10 के सभी कर्मचारियों को एक कलेक्शन में लाता है और प्रत्येक कर्मचारी का नाम प्रिंट करने के लिए उस पर इटररेट करता है, जिससे SQL और PL/SQL के बीच कॉन्टेक्स्ट स्विचेस कम होकर परफ़ॉर्मेंस बेहतर होती है।

DECLARE  
    -- Define a table-type collection based on the 'employees' table structure  
    TYPE emp_table IS TABLE OF employees%ROWTYPE;  
    v_emps emp_table;  -- Declare a variable of this type  

BEGIN  
    -- Bulk fetch employees from department 10 into the collection  
    SELECT * BULK COLLECT INTO v_emps FROM employees WHERE department_id = 10;  

    -- Loop through the collection and print employee names  
    FOR i IN 1..v_emps.COUNT LOOP  
        DBMS_OUTPUT.PUT_LINE('Employee: ' || v_emps(i).employee_name);  
    END LOOP;  

END;

इसी तरह, यह PL/SQL ब्लॉक FORALL का उपयोग बल्क अपडेट के लिए करता है, जिसमें IDs 101, 102, और 103 वाले कर्मचारियों की सैलरी 10% बढ़ाई जाती है।

DECLARE  
    -- Define a table-type collection for employee IDs  
    TYPE t_emp_ids IS TABLE OF employees.employee_id%TYPE;  
    -- Initialize collection with specific employee IDs  
    v_emp_ids t_emp_ids := t_emp_ids(101, 102, 103);  

BEGIN  
    -- Bulk update salaries by 10% for specified employee IDs  
    FORALL i IN 1..v_emp_ids.COUNT  
        UPDATE employees SET salary = salary * 1.10 WHERE employee_id = v_emp_ids(i);  

END;

12. डायनेमिक SQL और Ref Cursors क्या हैं?

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

निम्न PL/SQL ब्लॉक डायनेमिक SQL का उपयोग करके employees टेबल में पंक्तियों की संख्या गिनता है और परिणाम प्रिंट करता है। मुझे यह तरीका पसंद है क्योंकि यह लचीलापन प्रदान करता है।

DECLARE  
    v_table_name VARCHAR2(50) := 'employees';  -- Store table name  
    v_count NUMBER;  -- Variable to hold row count  

BEGIN  
    -- Dynamically count rows in the specified table  
    EXECUTE IMMEDIATE 'SELECT COUNT(*) FROM ' || v_table_name INTO v_count;  

    -- Print the total count  
    DBMS_OUTPUT.PUT_LINE('Total Employees: ' || v_count);  

END;  

Ref Cursors डायनेमिक कर्सर होते हैं जिन्हें रनटाइम पर खोला, फ़ेच और बंद किया जा सकता है, और ये प्रोग्राम यूनिट्स के बीच क्वेरी परिणामों को पास करने में सक्षम बनाते हैं।

निम्न PL/SQL ब्लॉक REF CURSOR का उपयोग करके विभाग 20 से कर्मचारी नाम फ़ेच और प्रिंट करता है। कर्सर को डायनेमिक रूप से खोला जाता है, लूप के माध्यम से इटररेट किया जाता है, और प्रोसेसिंग के बाद बंद कर दिया जाता है।

DECLARE  
    -- Define a REF CURSOR type  
    TYPE emp_ref_cursor IS REF CURSOR;  
    v_cursor emp_ref_cursor;  -- Declare a cursor variable  
    v_name employees.employee_name%TYPE;  -- Variable to store employee name  

BEGIN  
    -- Open the cursor for employees in department 20  
    OPEN v_cursor FOR SELECT employee_name FROM employees WHERE department_id = 20;  

    -- Fetch and print employee names in a loop  
    LOOP  
        FETCH v_cursor INTO v_name;  
        EXIT WHEN v_cursor%NOTFOUND;  
        DBMS_OUTPUT.PUT_LINE('Employee: ' || v_name);  
    END LOOP;  

    -- Close the cursor  
    CLOSE v_cursor;  

END;

पैरामीटराइज़्ड क्वेरी और DBMS_SQL पैकेज सहित गहन अध्ययन के लिए हमारा Dynamic SQL ट्यूटोरियल देखें।

13. म्यूटेटिंग टेबल एरर्स को कैसे संभालते हैं?

म्यूटेटिंग टेबल एरर्स तब होते हैं जब कोई ट्रिगर उसी टेबल को संशोधित करने का प्रयास करता है जिस पर वह ट्रिगर हुआ है। एक कम्पाउंड ट्रिगर, ट्रिगर निष्पादन को BEFORE, AFTER, और FOR EACH ROW जैसे कई चरणों में बाँटने देता है ताकि डायरेक्ट मोडिफिकेशन से जुड़ी समस्याओं से बचा जा सके।

नीचे दिया गया कम्पाउंड ट्रिगर salary_audit टेबल में सैलरी बदलावों को कुशलता से लॉग करता है, प्रत्येक रो अपडेट से पहले डेटा एकत्र करके और स्टेटमेंट के बाद बल्क इन्सर्ट करके, जिससे कॉन्टेक्स्ट स्विचेस घटते हैं और परफ़ॉर्मेंस बेहतर होती है।

CREATE OR REPLACE TRIGGER trg_salary_audit  
FOR UPDATE OF salary ON employees  -- Trigger fires on salary updates  
COMPOUND TRIGGER  

    -- Declare an associative array to store audit records  
    TYPE t_salary_audit IS TABLE OF salary_audit%ROWTYPE INDEX BY PLS_INTEGER;  
    v_audit_data t_salary_audit;  
    v_idx PLS_INTEGER := 0;  

    -- Before updating each row, store old and new salary details  
    BEFORE EACH ROW IS  
    BEGIN  
        v_idx := v_idx + 1;  
        v_audit_data(v_idx).employee_id := :OLD.employee_id;  
        v_audit_data(v_idx).old_salary := :OLD.salary;  
        v_audit_data(v_idx).new_salary := :NEW.salary;  
        v_audit_data(v_idx).change_date := SYSDATE;  
    END BEFORE EACH ROW;  

    -- After the statement, insert all audit records in bulk  
    AFTER STATEMENT IS  
    BEGIN  
        FORALL i IN 1..v_idx  
            INSERT INTO salary_audit VALUES v_audit_data(i);  
    END AFTER STATEMENT;  

END trg_salary_audit;

14. PL/SQL में ओवरलोडिंग क्या है?

ओवरलोडिंग एक पैकेज के भीतर समान नाम के साथ लेकिन अलग पैरामीटर्स वाले एक से अधिक प्रोसीजर या फंक्शंस परिभाषित करने की अनुमति देती है। यह पठनीयता और अनुरक्षणीयता बढ़ाती है क्योंकि समान ऑपरेशंस को कई तरीकों से करने का प्रावधान मिलता है।

नीचे दिए गए क्वेरी में पैकेज बॉडी दो ओवरलोडेड प्रोसीजर्स update_salary को इम्प्लीमेंट करती है: एक निर्दिष्ट राशि से कर्मचारी की सैलरी बढ़ाता है, जबकि दूसरा प्रभावी तिथि के साथ नई सैलरी सेट करता है, और इसके अनुसार employees टेबल को अपडेट करता है।

-- Create the package specification
CREATE OR REPLACE PACKAGE emp_pkg AS  
    -- Procedure to increment salary by a specified amount  
    PROCEDURE update_salary(p_emp_id NUMBER, p_increment NUMBER);

    -- Overloaded procedure to set a new salary with an effective date  
    PROCEDURE update_salary(p_emp_id NUMBER, p_new_salary NUMBER, p_effective_date DATE);
END emp_pkg;
/
-- Create the package body
CREATE OR REPLACE PACKAGE BODY emp_pkg AS  

    -- Procedure to increment salary by a specified amount  
    PROCEDURE update_salary(p_emp_id NUMBER, p_increment NUMBER) AS  
    BEGIN  
        UPDATE employees  
        SET salary = salary + p_increment  
        WHERE employee_id = p_emp_id;  
    END update_salary;  

    -- Overloaded procedure to set a new salary with an effective date  
    PROCEDURE update_salary(p_emp_id NUMBER, p_new_salary NUMBER, p_effective_date DATE) AS  
    BEGIN  
        UPDATE employees  
        SET salary = p_new_salary, last_update = p_effective_date  
        WHERE employee_id = p_emp_id;  
    END update_salary;  

END emp_pkg;
/

15. PL/SQL में कम्पाइलर डायरेक्टिव्स और प्रैग्माज़ क्या हैं?

PL/SQL को ऑप्टिमाइज़ करने और एक्सेप्शंस को संभालने के लिए कम्पाइलर डायरेक्टिव्स (PRAGMA) प्रदान करता है। सामान्य प्रैग्माज़ में शामिल हैं:

  • PRAGMA EXCEPTION_INIT: किसी यूज़र-परिभाषित एक्सेप्शन को Oracle एरर कोड से संबद्ध करता है।

  • PRAGMA SERIALLY_REUSABLE: स्केलेबिलिटी के लिए पैकेज मेमोरी उपयोग को अनुकूलित करता है।

निम्न PL/SQL ब्लॉक अमान्य सैलरी वाले कर्मचारी के इन्सर्शन को हैंडल करता है, जिसमें कस्टम एक्सेप्शन e_invalid_salary को एरर कोड -20001 से मैप किया गया है। यदि एक्सेप्शन उठता है, तो यह एक एरर संदेश प्रिंट करता है।

DECLARE  
    e_invalid_salary EXCEPTION;  -- Declare custom exception for invalid salary  
    PRAGMA EXCEPTION_INIT(e_invalid_salary, -20001);  -- Associate exception with error code -20001  
BEGIN  
    -- Attempt to insert an employee with invalid salary  
    INSERT INTO employees (employee_id, salary) VALUES (999, -1000);  
EXCEPTION  
    -- Handle the custom exception and print a message  
    WHEN e_invalid_salary THEN  
        DBMS_OUTPUT.PUT_LINE('Invalid salary detected!');  
END;  

16. PL/SQL को ट्रेस और डिबग करने के विभिन्न तरीके क्या हैं?

PL/SQL परफ़ॉर्मेंस को ट्रेस और डिबग करने के लिए कई बिल्ट-इन पैकेज प्रदान करता है। सामान्य तरीके हैं एक्ज़िक्यूशन फ्लो ट्रैक करने के लिए DBMS_TRACE, सेशन गतिविधि मॉनिटर करने के लिए DBMS_APPLICATION_INFO, और सेशन-स्तरीय डायग्नोस्टिक जानकारी जुटाने के लिए DBMS_SESSION का उपयोग।

नीचे दिया गया क्वेरी पहले DBMS_SESSION.set_sql_trace(TRUE) का उपयोग करके SQL ट्रेसिंग सक्षम करता है, फिर मॉनिटरिंग के लिए DBMS_APPLICATION_INFO.set_client_info() के साथ क्लाइंट-विशिष्ट सेशन जानकारी सेट करता है। PL/SQL ब्लॉक निष्पादित होता है, जो एक UPDATE ऑपरेशन का सिमुलेशन करता है। अंत में, DBMS_SESSION.set_sql_trace(FALSE) का उपयोग करके ट्रेसिंग को निष्क्रिय कर दिया जाता है।

-- Enable tracing for the current session using DBMS_SESSION
BEGIN
   -- Start session-level tracing
   DBMS_SESSION.set_sql_trace(TRUE);
END;
/

-- Set application information using DBMS_APPLICATION_INFO
BEGIN
   -- Set the application name and action for session monitoring
   DBMS_APPLICATION_INFO.set_client_info('Trace Debug Session');
   DBMS_APPLICATION_INFO.set_action('Debugging PL/SQL Code');
END;
/

-- Example PL/SQL block that simulates a process for debugging
DECLARE
   v_employee_id NUMBER := 100;
BEGIN
   -- Example query to fetch employee details
   FOR rec IN (SELECT first_name, last_name FROM employees WHERE employee_id = v_employee_id) LOOP
      DBMS_OUTPUT.put_line('Employee: ' || rec.first_name || ' ' || rec.last_name);
   END LOOP;
   
   -- Simulate some logic that could be traced
   IF v_employee_id = 100 THEN
      DBMS_OUTPUT.put_line('Employee ID is 100');
   END IF;
END;
/

-- Disable tracing after the session is complete
BEGIN
   -- Stop session-level tracing
   DBMS_SESSION.set_sql_trace(FALSE);
END;
/

Scenario-Based PL/SQL Interview Questions

वास्तविक-जीवन एंटरप्राइज़ एप्लिकेशंस में PL/SQL का उपयोग जटिल बिज़नेस लॉजिक संभालने के लिए किया जाता है। इंटरव्यूअर अक्सर उम्मीदवार की यह क्षमता परखते हैं कि वह व्यावहारिक परिदृश्यों में PL/SQL को कैसे लागू करता/करती है। नीचे कुछ प्रमुख चुनौतियाँ और उन्हें हल करने की रणनीतियाँ दी गई हैं।

इस अगले और अंतिम सेक्शन के लिए, यदि आप इंटरव्यू दे रहे हैं, तो मैं आपको सुझाव दूँगा/दूँगी कि आप इस टेम्पलेट के अनुसार उत्तर तैयार करने के बारे में सोचें, लेकिन, बेशक, अपने विशेष उद्योग के लिए या अपने अनुभव को दर्शाने के लिए अपने उत्तर को पुनः उन्मुख करने की कोशिश करें। यही बात तब भी लागू होती है यदि आप किसी उम्मीदवार का इंटरव्यू ले रहे हैं और प्रश्न पूछने और उत्तर की गहराई आँकने के तरीकों के लिए विचार चाहते हैं, ऐसी स्थिति में मुझे आशा है कि यह सेक्शन आपके प्रश्नों और मूल्यांकन मानदंडों दोनों के लिए प्रेरणा का काम करेगा।

17. अत्यधिक समवर्ती (concurrent) वातावरण में ट्रिगर्स कैसे डिज़ाइन करेंगे?

मान लें कि आपको एक बिज़नेस नियम लागू करना है जिसमें किसी कर्मचारी की सैलरी को एक दिन में एक बार से अधिक अपडेट नहीं किया जा सकता। लेकिन डेटाबेस में ट्रांज़ैक्शन का उच्च समवर्तीपन है, और एक साधारण ट्रिगर कंटेंशन या परफ़ॉर्मेंस समस्याएँ पैदा कर सकता है।

हर अपडेट पर फायर होने वाले रो-स्तरीय ट्रिगर के बजाय, जो परफ़ॉर्मेंस धीमी कर सकता है, लॉग टेबल के साथ एक स्टेटमेंट-स्तरीय ट्रिगर का उपयोग करें ताकि एक ही दिन में कई सैलरी अपडेट रोके जा सकें।

उदाहरण के लिए, नीचे दिया गया ट्रिगर salary_update_log टेबल की जाँच करके एक ही दिन में किसी कर्मचारी की अनेक सैलरी अपडेट को रोकता है। यदि आज सैलरी पहले ही अपडेट हो चुकी है, तो एक एरर उठाया जाता है; अन्यथा, अपडेट तिथि को लॉग किया जाता है।

-- Create a table to log the last salary update for each employee
CREATE TABLE salary_update_log (
    employee_id NUMBER PRIMARY KEY,  -- Employee ID as primary key
    last_update DATE  -- Date of the last salary update
);

-- Create or replace a compound trigger to prevent multiple salary updates on the same day
CREATE OR REPLACE TRIGGER trg_prevent_multiple_salary_update  
FOR UPDATE OF salary ON employees  
COMPOUND TRIGGER  

    -- Declare a variable to store last salary update date per row
    TYPE emp_log_type IS TABLE OF DATE INDEX BY PLS_INTEGER;
    emp_log emp_log_type;

    BEFORE STATEMENT IS  
    BEGIN  
        -- Load existing salary update logs into memory for reference
        FOR rec IN (SELECT employee_id, last_update FROM salary_update_log) LOOP  
            emp_log(rec.employee_id) := rec.last_update;  
        END LOOP;  
    END BEFORE STATEMENT;  

    BEFORE EACH ROW IS  
    BEGIN  
        -- Check if an entry exists for this employee
        IF emp_log.EXISTS(:NEW.employee_id) THEN  
            -- Validate if salary was updated today
            IF emp_log(:NEW.employee_id) = TRUNC(SYSDATE) THEN  
                RAISE_APPLICATION_ERROR(-20010, 'Salary can only be updated once per day');  
            ELSE  
                -- Update log in memory
                emp_log(:NEW.employee_id) := TRUNC(SYSDATE);  
            END IF;  
        ELSE  
            -- Insert a new log entry into memory
            emp_log(:NEW.employee_id) := TRUNC(SYSDATE);  
        END IF;  
    END BEFORE EACH ROW;  

    AFTER STATEMENT IS  
    BEGIN  
        -- Apply changes to the log table after all row updates
        FOR i IN emp_log.FIRST .. emp_log.LAST LOOP  
            MERGE INTO salary_update_log l  
            USING (SELECT i AS employee_id, emp_log(i) AS last_update FROM DUAL) s  
            ON (l.employee_id = s.employee_id)  
            WHEN MATCHED THEN  
                UPDATE SET l.last_update = s.last_update  
            WHEN NOT MATCHED THEN  
                INSERT (employee_id, last_update) VALUES (s.employee_id, s.last_update);  
        END LOOP;  
    END AFTER STATEMENT;  

END trg_prevent_multiple_salary_update;

ऊपर दिया गया उदाहरण रो-स्तरीय लॉकिंग घटाएगा और बल्क अपडेट के दौरान ट्रांज़ैक्शन कॉन्फ्लिक्ट्स को न्यूनतम करेगा।

18. विश्वसनीयता के लिए बड़े ट्रांज़ैक्शंस को छोटे हिस्सों में कैसे बाँटेंगे?

मान लें कि किसी बैंकिंग सिस्टम में लाखों कस्टमर अकाउंट्स के लिए इंटरेस्ट रेट एडजस्ट करने हेतु बल्क अपडेट की आवश्यकता है। एकल बड़ा ट्रांज़ैक्शन चलाने से टेबल्स लंबे समय तक लॉक हो सकती हैं या रोलबैक विफल हो सकता है।

इस स्थिति में, डेटा को क्रमिक रूप से प्रोसेस करने और कंटेंशन से बचने के लिए COMMIT को बैचों में उपयोग करते हुए बल्क प्रोसेसिंग करें।

नीचे दिया गया PL/SQL ब्लॉक BULK COLLECT का उपयोग करके अकाउंट IDs फ़ेच करता है और फिर उन पर इटररेट करते हुए इंटरेस्ट रेट में 5% की वृद्धि करता है। यह हर 1000 अपडेट्स के बाद बदलावों को कमिट करता है ताकि परफ़ॉर्मेंस बेहतर हो और संसाधन उपयोग घटे। अंत में शेष अपडेट्स के लिए अंतिम कमिट किया जाता है।

DECLARE  
    -- Define a collection type for account IDs  
    TYPE t_accounts IS TABLE OF NUMBER;  -- Use NUMBER instead of referencing accounts.account_id
    v_account_ids t_accounts;  -- Variable to store account IDs  
    v_batch_size CONSTANT NUMBER := 1000;  -- Batch size for commits  

BEGIN  
    -- Bulk collect all account IDs into the collection  
    SELECT account_id BULK COLLECT INTO v_account_ids FROM accounts;  

    -- Loop through each account ID to update the interest rate  
    FOR i IN 1 .. v_account_ids.COUNT LOOP  
        UPDATE accounts  
        SET interest_rate = interest_rate * 1.05  -- Increase interest rate by 5%  
        WHERE account_id = v_account_ids(i);  

        -- Commit after every 1000 updates  
        IF MOD(i, v_batch_size) = 0 THEN  
            COMMIT;  
        END IF;  
    END LOOP;  

    COMMIT; -- Final commit for any remaining updates  
END;
/

यह समाधान पेरोल जैसे वित्तीय सिस्टम में ट्रांज़ैक्शन विफलताओं को रोककर विश्वसनीयता सुनिश्चित करेगा।

हमारा SQL Transactions गाइड COMMIT, ROLLBACK, SAVEPOINT, और आइसोलेशन लेवल्स को गहराई से कवर करता है — ये सभी अवधारणाएँ परिदृश्य-आधारित इंटरव्यू प्रश्नों में सामने आती हैं।

19. अनुरक्षणीयता के लिए जटिल लॉजिक को पैकेजों में कैसे संगठित करेंगे?

एक रिटेल कंपनी को एक ऑर्डर प्रोसेसिंग सिस्टम इम्प्लीमेंट करना है, जिसमें कई चरण शामिल हैं: इन्वेंटरी उपलब्धता जाँचना, स्टॉक आरक्षित करना, डिस्काउंट गणना करना, और ट्रांज़ैक्शन हिस्ट्री लॉग करना।

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

नीचे दिया गया पैकेज स्पेसिफिकेशन ऑर्डर प्रोसेसिंग के लिए फंक्शंस और प्रोसीजर परिभाषित करता है, जिनमें इन्वेंटरी जाँच, स्टॉक आरक्षण, डिस्काउंट गणना, और ट्रांज़ैक्शन स्टेटस लॉग करना शामिल है। यह ऑर्डर-संबंधित कार्यों को हैंडल करने का मॉड्युलर दृष्टिकोण प्रदान करता है।

-- Create a package specification for order processing functions and procedures
CREATE PACKAGE order_processing_pkg AS  

    -- Function to check if enough inventory is available for the product
    FUNCTION check_inventory(p_product_id NUMBER, p_quantity NUMBER) RETURN BOOLEAN;  

    -- Procedure to reserve stock for a specific order
    PROCEDURE reserve_stock(p_order_id NUMBER, p_product_id NUMBER, p_quantity NUMBER);  

    -- Function to calculate discount based on customer and total amount
    FUNCTION calculate_discount(p_customer_id NUMBER, p_total_amount NUMBER) RETURN NUMBER;  

    -- Procedure to log the status of a transaction
    PROCEDURE log_transaction(p_order_id NUMBER, p_status VARCHAR2);  

END order_processing_pkg;

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

-- Create the package body implementing the functions and procedures for order processing
CREATE PACKAGE BODY order_processing_pkg AS  

    -- Function to check if sufficient inventory is available for the product
    FUNCTION check_inventory(p_product_id NUMBER, p_quantity NUMBER) RETURN BOOLEAN AS  
        v_available_qty NUMBER;  -- Variable to store available quantity  
    BEGIN  
        -- Retrieve the available quantity from inventory
        SELECT stock_quantity INTO v_available_qty FROM inventory WHERE product_id = p_product_id;  
        -- Return true if enough stock is available, otherwise false
        RETURN v_available_qty >= p_quantity;  
    END check_inventory;  

    -- Procedure to reserve stock for a specific order
    PROCEDURE reserve_stock(p_order_id NUMBER, p_product_id NUMBER, p_quantity NUMBER) AS  
    BEGIN  
        -- Deduct the ordered quantity from the inventory
        UPDATE inventory SET stock_quantity = stock_quantity - p_quantity WHERE product_id = p_product_id;  
    END reserve_stock;  

    -- Function to calculate a discount based on the total order amount
    FUNCTION calculate_discount(p_customer_id NUMBER, p_total_amount NUMBER) RETURN NUMBER AS  
        v_discount NUMBER := 0;  -- Initialize discount to 0  
    BEGIN  
        -- Apply 10% discount if the total amount is greater than 500
        IF p_total_amount > 500 THEN  
            v_discount := p_total_amount * 0.10;  
        END IF;  
        -- Return the calculated discount
        RETURN v_discount;  
    END calculate_discount;  

    -- Procedure to log the transaction status
    PROCEDURE log_transaction(p_order_id NUMBER, p_status VARCHAR2) AS  
    BEGIN  
        -- Insert a log entry for the order status
        INSERT INTO order_log (order_id, status, log_date) VALUES (p_order_id, p_status, SYSDATE);  
    END log_transaction;  

END order_processing_pkg;

20. उच्च-ट्रांज़ैक्शन सिस्टम में डेडलॉक्स को कैसे हैंडल करेंगे?

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

समस्या सुलझाने के लिए, हमेशा सभी ट्रांज़ैक्शंस में पंक्तियों को एक सुसंगत क्रम में लॉक करें। साथ ही, अनिश्चितकालीन प्रतीक्षा से बचने के लिए NOWAIT या SKIP LOCKED क्लॉज़ का उपयोग करें।

उदाहरण के लिए, नीचे दिया गया PL/SQL ब्लॉक FOR UPDATE NOWAIT क्लॉज़ का उपयोग करते हुए अपडेट के लिए अकाउंट्स टेबल में एक विशिष्ट पंक्ति को लॉक करने का प्रयास करता है, जो किसी अन्य सत्र द्वारा पंक्ति पहले से लॉक होने पर ट्रांज़ैक्शन को तुरंत विफल कर देता है। लॉक करने के बाद, यह ट्रांज़ैक्शन स्टेटस अपडेट करता है और बदलावों को कमिट करता है। यदि कोई त्रुटि होती है, तो यह एक्सेप्शन पकड़ता है और एरर संदेश प्रिंट करता है।

DECLARE  
    v_balance NUMBER(15,2);  -- Declare variable to store the account balance  
BEGIN  
    -- Lock the account row for update to prevent other sessions from modifying it  
    SELECT balance INTO v_balance FROM accounts  
    WHERE account_id = 101 FOR UPDATE NOWAIT;  

    -- Update the transaction status to 'Processed' for all transactions related to this account  
    UPDATE transactions  
    SET status = 'Processed'  
    WHERE account_id = 101 AND status = 'Pending';  -- Update only pending transactions  

    COMMIT;  -- Commit the changes  

EXCEPTION  
    -- Handle errors, such as locking issues or unexpected exceptions  
    WHEN OTHERS THEN  
        DBMS_OUTPUT.PUT_LINE('Transaction failed: ' || SQLERRM);  
        ROLLBACK;  -- Ensure rollback in case of failure  
END;
/

इसी प्रकार, यह PL/SQL ब्लॉक पेंडिंग ट्रांज़ैक्शंस को FOR UPDATE SKIP LOCKED के साथ अपडेट के लिए लॉक करके प्रोसेस करता है, जिससे वह पहले से अन्य सत्रों द्वारा लॉक की गई पंक्तियों को छोड़ देता है। यह प्रत्येक ट्रांज़ैक्शन की स्थिति को 'Processing' में अपडेट करता है और अंत में बदलावों को कमिट करता है।

DECLARE  
    -- Declare a cursor to select pending transactions and lock rows for update
    CURSOR c_pending_txns IS  
        SELECT transaction_id FROM transactions WHERE status = 'Pending' FOR UPDATE SKIP LOCKED;  -- Skip locked rows  

BEGIN  
    -- Loop through the pending transactions
    FOR txn IN c_pending_txns LOOP  
        -- Update the status of each transaction to 'Processing'
        UPDATE transactions SET status = 'Processing' WHERE transaction_id = txn.transaction_id;  
    END LOOP;  
    COMMIT;  -- Commit the changes to finalize the transaction updates  
END;

Final Thoughts

Oracle-केंद्रित भूमिकाओं के लिए, नियोक्ता ऐसे उम्मीदवारों की तलाश करते हैं जो सही PL/SQL कोड लिख सकें, वास्तविक-जीवन की चुनौतियों को संभाल सकें, और डेटाबेस परफ़ॉर्मेंस को ऑप्टिमाइज़ कर सकें। मैं PL/SQL Language Reference पर आधिकारिक Oracle डॉक्यूमेंटेशन और हमारे SQL Injection ट्यूटोरियल की जाँच करने की सलाह देता/देती हूँ — डायनेमिक PL/SQL के माध्यम से SQL इंजेक्शन एक सामान्य सीनियर-स्तरीय इंटरव्यू विषय है, जिसके लिए गहन गाइड और सर्वोत्तम प्रथाएँ उपलब्ध हैं। interactive Oracle FreeSQL playground Oracle के क्लाउड-आधारित प्लेटफ़ॉर्म तक पहुँच प्रदान करता है जहाँ आप ऑनलाइन PL/SQL क्वेरी चला सकते हैं। मैं आपको Oracle Community से जुड़ने के लिए भी प्रोत्साहित करता/करती हूँ ताकि आप Oracle विशेषज्ञों और डेवलपर्स के साथ संवाद कर सकें, और Stack Overflow फोरम पर PL/SQL-संबंधित प्रश्नों के समाधान पा सकें।

हालाँकि, किसी संरचित लर्निंग पाथ का कोई विकल्प नहीं। इसी कारण, मैं हमारे Introduction to Oracle SQL कोर्स की अनुशंसा करता/करती हूँ, जो SQL की बुनियाद से लेकर उन्नत Oracle प्रोग्रामिंग तक का सबसे संरचित मार्ग प्रदान करता है। साथ ही, यदि आप डेटाबेस के साथ काम करने के अपने ज्ञान को आगे बढ़ाना चाहते हैं, तो मैं हमारे Database Design कोर्स को भी लेने की सलाह देता/देती हूँ, जहाँ आप डेटाबेस बनाना और प्रबंधित करना तथा अपनी आवश्यकताओं के लिए उपयुक्त DBMS चुनना सीखेंगे। अंत में, हमारा Associate Data Engineer in SQL करियर ट्रैक आज़माएँ, ताकि आप डेटा इंजीनियरिंग और डेटा वेयरहाउसिंग की बुनियाद सीख सकें। 

अंत में, यदि आप उम्मीदवारों का इंटरव्यू ले रहे हैं और दूसरों को भी अपस्किल करना चाहते हैं, तो हमारी DataCamp for Business टीम से जुड़ें। DataCamp पूरे टीम को हैंड्स-ऑन प्रोजेक्ट्स और कस्टम लर्निंग पाथ्स के साथ अपस्किल कर सकता है। टीमों को एक ही जगह पर संरचित करिकुला, हैंड्स-ऑन प्रोजेक्ट्स, और प्रोग्रेस ट्रैकिंग मिलती है। हमारी टीम से आज ही जुड़ें और अपने संगठन की सीखने की पहल को आत्मविश्वास और विश्वसनीयता के साथ आगे बढ़ाएँ।

PL SQL FAQs

PL/SQL क्या है, और यह SQL से कैसे भिन्न है?

PL/SQL Oracle द्वारा विकसित एक प्रक्रियात्मक भाषा है, जो कंट्रोल स्ट्रक्चर्स और एरर हैंडलिंग की सुविधा देती है, जबकि SQL घोषणात्मक है और डेटा प्राप्ति/हेरफेर को संभालता है।

PL/SQL पैकेज क्या है?

मॉड्युलर प्रोग्रामिंग और पुन: उपयोग के लिए संबंधित प्रोसीजर, फंक्शंस, वेरिएबल्स, और कर्सर्स का एक संग्रह।

प्रोसीजर और फंक्शन में क्या अंतर है?

प्रोसीजर्स वह क्रिया करते हैं जो कोई मान वापस नहीं करती, जबकि फंक्शंस कोई मान लौटाते हैं जिसे क्वेरी में उपयोग किया जा सकता है।

PL/SQL में ट्रिगर्स क्या हैं?

स्वचालित क्रियाएँ जो INSERT, UPDATE, DELETE ऑपरेशंस से पहले या बाद में निष्पादित होती हैं।

PL/SQL में बल्क प्रोसेसिंग क्या है?

बल्क प्रोसेसिंग (BULK COLLECT, FORALL) बड़े डेटासेट हैंडल करते समय PL/SQL और SQL इंजनों के बीच कॉन्टेक्स्ट स्विचेज़ को घटाकर परफ़ॉर्मेंस बढ़ाती है।

PL/SQL में BULK COLLECT और FORALL में क्या अंतर है?

BULK COLLECT कई पंक्तियों को SQL से एक ही राउंड ट्रिप में PL/SQL कलेक्शन में लाता है, जो रो-बाय-रो SELECT INTO स्टेटमेंट्स की जगह लेता है। FORALL बल्क DML (insert, update, delete) करता है, जिसमें मानों के कलेक्शन को एक बैच में SQL इंजन तक भेजा जाता है। डेटा पढ़ने के लिए BULK COLLECT का उपयोग करें और लिखने के लिए FORALL का। दोनों SQL और PL/SQL इंजनों के बीच कॉन्टेक्स्ट स्विचेज़ घटाते हैं, जो डेटा-इंटेन्सिव PL/SQL ब्लॉक्स में परफ़ॉर्मेंस ओवरहेड का मुख्य स्रोत है।

PL/SQL में SQL इंजेक्शन को कैसे रोकते हैं?

PL/SQL में मुख्य जोखिम वह डायनेमिक SQL है जो यूज़र इनपुट को स्ट्रिंग में जोड़कर EXECUTE IMMEDIATE के लिए बनाता है। इसके बजाय बाइंड वेरिएबल्स का उपयोग करें: EXECUTE IMMEDIATE 'SELECT ... WHERE id = :id' USING p_id। बाइंड वेरिएबल्स कभी भी SQL सिंटैक्स के रूप में इंटरप्रेट नहीं होते, इसलिए इंजेक्ट किया गया कोड निष्पादित नहीं हो सकता। जहाँ स्टेटमेंट स्ट्रक्चर को डायनेमिक रूप से बदलना आवश्यक हो (टेबल/कॉलम नाम), वहाँ अनुमत मानों की एक व्हाइटलिस्ट उपयोग करें जिसे जोड़ने से पहले वैलिडेट किया जाए, और न्यूनतम-अधिकार (least-privilege) डाटाबेस ग्रांट्स लागू करें ताकि यदि इंजेक्शन हो भी जाए तो हमलावर बहुत कुछ न कर सके।

विषय