2010-02-25 9 views
14

मैं कुछ हद तक खतरनाक रूप से कोड में कोड के उपखंडों को समूहबद्ध कर रहा हूं ... जब यह सही लगता है तो अंत ब्लॉक। अधिकांशतः जब मैं एक लंबी संग्रहीत प्रक्रिया पर काम कर रहा हूं और एक स्थान पर एक अस्थायी चर की आवश्यकता है तो मैं इसे कोड के उस हिस्से के लिए घोषित करूंगा। मैं यह भी करता हूं जब मैं कोड के विशिष्ट टुकड़े के लिए अपवादों को पहचानना और संभालना चाहता हूं।मुझे पीएल/एसक्यूएल BEGIN कब घोंसला चाहिए ... अंत ब्लॉक?

किसी भी अन्य कारणों से किसी को प्रक्रिया, फ़ंक्शन या पीएल/एसक्यूएल का एक और बड़ा ब्लॉक क्यों अवरुद्ध करना चाहिए?

उत्तर

17

आप इस तरह स्थानीय स्तर पर अपवाद को संभालने के लिए चाहते हैं:

begin 
    for emp_rec in (select * from emp) loop 
     begin 
     my_proc (emp_rec); 
     exception 
     when some_exception then 
      log_error('Failed to process employee '||emp_rec.empno); 
     end; 
    end loop; 
end; 

इस उदाहरण में, अपवाद नियंत्रित किया जाता है और फिर हम पर ले जाने और अगले कर्मचारी की प्रक्रिया।

declare 
    l_var1 integer; 
    -- lots of variables 
begin 
    -- lots of lines of code 
    ... 
    for emp_rec in (select * from emp) loop 
     declare 
     l_localvar integer := 0; 
     begin 
     -- Use l_localvar 
     ... 
     end 
    end loop; 

end; 

मन आप, यह अक्सर एक संकेत है कि अपने कार्यक्रम बहुत बड़ा है और टूट जाना चाहिए करना चाहते:

एक अन्य प्रयोग स्थानीय चर है कि इस तरह गुंजाइश सीमित है घोषित करने के लिए है

declare 
    l_var1 integer; 
    -- lots of variables 
    ... 
    procedure local_proc (emp_rec emp%rowtype): 
     l_localvar integer := 0; 
    begin 
     -- Use l_localvar 
     ... 
    end 
begin 
    -- lots of lines of code 
    ... 
    for emp_rec in (select * from emp) loop 
     local_proc (emp_rec); 
    end loop; 

end; 
+1

+1। 'प्रारंभ/समाप्ति' ब्लॉक के लिए सबसे अच्छा अभ्यास अज्ञात ब्लॉक है, नाम ब्लॉक (प्रक्रिया/फ़ंक्शन) या विशिष्ट अपवादों को संभालने के लिए, जैसा कि पहले उदाहरण में है। 'प्रारंभ/समाप्ति' ब्लॉक के भीतर 'घोषित' कथन को निस्तारण करना, मैं एक प्रोग्रामिंग बग कहूंगा, क्योंकि यह परिवर्तनीय स्कोप टकराव की संभावना का परिचय देता है, और ये डीबग करने के लिए दर्द हैं। –

1

जब मैं ब्लॉक के भीतर मौजूद डेटा के लिए विशिष्ट प्रक्रियाएं बनाना चाहता हूं तो मैं घोंसला ब्लॉक करता हूं। यहाँ एक काल्पनिक उदाहरण है:

BEGIN 
    FOR customer IN customers LOOP 
    DECLARE 

     PROCEDURE create_invoice(description VARCHAR2, amount NUMBER) IS 
     BEGIN 
     some_complicated_customer_package.create_invoice(
      customer_id => customer.customer_id, 
      description => description, 
      amount => amount 
     ); 
     END; 

    BEGIN 

     /* All three calls are being applied to the current customer, 
     even if we're not explicitly passing customer_id. 
     */ 
     create_invoice('Telephone bill', 150.00); 
     create_invoice('Internet bill', 550.75); 
     create_invoice('Television bill', 560.45); 

    END; 
    END LOOP; 
END; 

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

+0

मुझे आवश्यकता नहीं दिखाई दे रही है - आप पहले से ही एक लूप के भीतर हैं। दूसरा, क्या लूप के बाहर संग्रहीत प्रक्रिया घोषणा नहीं होनी चाहिए? –

+0

@ ओएमजी टट्टू: इस उदाहरण का उद्देश्य इस तथ्य को स्पष्ट करना था कि पैरामीटर के माध्यम से जानकारी को पास किए बिना उस ब्लॉक के डेटा का लाभ उठाने के लिए ब्लॉक के भीतर प्रक्रियाओं को घोषित करना संभव है। आप सही हैं, अगर आप 'create_invoice' के पैरामीटर के रूप में स्पष्ट रूप से 'customer_id' को पास करना चाहते हैं, तो उसे लूप के बाहर घोषित करना होगा। मेरे अनुभव में, मैंने परिस्थितियों में भाग लिया है जहां ब्लॉक की जानकारी का लाभ उठाने के लिए यह स्पष्ट है। –

0

नेस्टेड BEGIN/END ब्लॉक रखने का एक कारण कोड के एक विशिष्ट स्थानीय अनुभाग के लिए अपवादों को संभालने में सक्षम होना है और अपवाद संसाधित होने पर संभावित रूप से प्रसंस्करण जारी रखना है।

संबंधित मुद्दे