2015-10-15 7 views
7

अजीब चीज़ मिला। समझ में नहीं आता क्यों ओरेकल इस क्वेरी के लिए अनुमति देने और क्यों यह निष्पादन के बाद cnt चर परिवर्तन नहीं करता है:ओरेकल। समझ में नहीं आता है कि कैसे subquery चयन के साथ काम करता है

declare cnt number; 
begin 
for r in (Select count(1) into cnt from v$session) loop 
    dbms_output.put_line(cnt); 
END LOOP; 
end; 

Select count(1) from v$session रिटर्न रिक्त नहीं मूल्य

बेशक

मुझे समझ है:

  1. इस स्थिति में FOR की आवश्यकता नहीं है। Count बिना INTO केवल एक पंक्ति को बरकरार रखता है।
  2. कि मैं इसे INTO के बिना उपयोग कर सकता हूं और यह काम करेगा।

बस उत्सुक है कि यह उपरोक्त क्वेरी में कैसे और क्यों काम करता है।

यह क्योंकि सामान्य स्थिति में ओरेकल रिटर्न संकलन त्रुटि ORA-06550

declare cnt number; 
begin 
     select count(1) from (Select count(1) into cnt from v$session) 
end; 
or 

और पहली क्वेरी काम करता है, यही कारण है कि ओरेकल SELECT INTO साथ सबक्वेरी अनुमति देते हैं अजीब बात है - क्यों यह cnt मूल्य सही ढंग से वापस नहीं करता है?

+1

कृपया मेरे उत्तर पर एक नज़र डालें। आपको चुनिंदा कथन के लिए अपने कॉलम का नाम देना चाहिए। तालिका पंक्ति की तरह 'आर' संभाल लें। –

उत्तर

2

बहुत दिलचस्प, मैं कहता हूँ कि हम इस को छोड़कर एक बग है यह एक सौम्य है। INTO cnt सा वैध PL/SQL है लेकिन इस संदर्भ है, जो एक साधारण परीक्षण मामले से साबित किया जा सकता में नजरअंदाज कर दिया है:

declare cnt number; 
begin 
for r in (select count(1) into cnt from dual) loop 
    dbms_output.put_line('cnt=' || cnt); 
    dbms_output.put_line('r=' || r."COUNT(1)"); 
end loop; 
end; 

आप देख सकते हैं, INTO खंड पर ध्यान नहीं दिया जाता है, और अपेक्षा के अनुरूप r रिकॉर्ड है सही ढंग से आबादी। मेरे 11 जीआर 2 उदाहरण पर आउटपुट:

cnt= 
r=1 
4

सही एसक्यूएल बयान

इस

declare cnt number; 
begin 
for r in (Select count(1) as cnt from v$session) loop 
    dbms_output.put_line(r.cnt); 
END LOOP; 
end; 

स्पष्टीकरण

select_statement

एसक्यूएल SELECT कथन (नहीं PL/SQL का चयन करें जांच बयान) का प्रयास करें। Select_statement के लिए, पीएल/एसक्यूएल घोषित करता है, खुलता है, से प्राप्त करता है, और एक निहित कर्सर बंद करता है। हालांकि, क्योंकि select_statement एक स्वतंत्र कथन नहीं है, निहित कर्सर आंतरिक है-आप इसे एसक्यूएल नाम से संदर्भित नहीं कर सकते हैं।

देख http://docs.oracle.com/cd/E11882_01/appdev.112/e25519/cursor_for_loop_statement.htm#LNPLS1155

cnt चर नजरअंदाज कर दिया है, इस निम्न उदाहरण से साबित किया जा सकता है, क्योंकि कोई त्रुटि उठाया है:

declare 
    cnt  number; 
    a_varchar varchar2(1); 
begin 
    for r in (Select 'AA' into a_varchar from v$session) loop 
    dbms_output.put_line(a_varchar); 
    end loop; 
end; 
+0

@RaduGheorghiu मैंने बिना किसी समस्या के इसका परीक्षण किया है। –

+0

मेरा बुरा, मैंने अपने कोड में गलती की है। तुम सही हो। –

+0

हाँ, यह काम करता है। जवाब देने के लिए +1।लेकिन यह स्पष्ट नहीं करता है कि यह –

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