2013-04-24 6 views
5

मैं ऑरैकल कोड ब्लॉक में संग्रह का उपयोग कर रहा हूं क्योंकि कोई टेबल वैरिएबल नहीं है (जैसे एमएस एसक्यूएल सर्वर में)।ओरेकल संग्रह जहां क्लॉज

DECLARE 
    TYPE I_NAME IS TABLE OF NVARCHAR2(512);  
    I_ITEMNAME  I_NAME := I_NAME(); 
BEGIN 

संग्रह संग्रह भरने के लिए मैं "बल्क संग्रह INTO__ITEMNAME" का उपयोग कर रहा हूं।
मैं इस संग्रह का चयन WHERE खंड में एक SELECT क्वेरी में करना चाहता हूं लेकिन इसे करने के लिए विधि नहीं ढूंढ पा रहा हूं। वर्तमान में मैं और लूप का उपयोग कर रहा हूं और आइटम को एक-एक करके प्राप्त कर रहा हूं।
कैसे मैं टीबीएल से की तरह

चुनें * कहां खंड किसी चीज़ I_ITEMNAME में जहां कर्नल में सीधे संग्रह का उपयोग कर सकते हैं?

धन्यवाद,

उत्तर

9

आप एक एसक्यूएल खंड में एक स्थानीय रूप से घोषित संग्रह का उपयोग नहीं कर सकते हैं:

declare 
    type i_name is table of nvarchar2(512); 
    i_itemname i_name := i_name(); 
    c number; 
begin 
    select distinct owner bulk collect into i_itemname from all_objects; 
    dbms_output.put_line(i_itemname.count); 
    select count(*) into c 
    from all_tables 
    where owner in (select * from table(i_itemname)); 
    dbms_output.put_line(c); 
end; 
/

    where owner in (select * from table(i_itemname)); 
             * 
ERROR at line 10: 
ORA-06550: line 10, column 41: 
PLS-00642: local collection types not allowed in SQL statements 
ORA-06550: line 10, column 35: 
PL/SQL: ORA-22905: cannot access rows from a non-nested table item 
ORA-06550: line 8, column 5: 
PL/SQL: SQL Statement ignored 

लेकिन आप कर सकते हैं अगर यह, स्कीमा स्तर पर घोषित की गई अनिवार्य रूप से इतना है कि एसक्यूएल के बारे में जानता प्रकार, न सिर्फ PL/SQL:

create type i_name is table of nvarchar2(512); 
/

Type created. 

declare 
    i_itemname i_name := i_name();  
    c number; 
begin 
    select distinct owner bulk collect into i_itemname from all_objects; 
    dbms_output.put_line(i_itemname.count); 
    select count(*) into c from all_tables 
    where owner in (select * from table(i_itemname)); 
    dbms_output.put_line(c); 
end; 
/

No errors. 
18 
128 

PL/SQL procedure successfully completed. 

तुम भी table निर्माण शामिल हो सकते हैं के बजाय एक सु का उपयोग bquery:

... 
    select count(*) into c 
    from table(i_itemname) t 
    join all_tables at on at.owner = t.column_value; 
... 

मैं बिल्कुल स्पष्ट नहीं हूं कि आप क्या कर रहे हैं। (यदि आप किसी और चीज़ के लिए संग्रह का उपयोग नहीं कर रहे हैं, तो आप केवल कच्चे डेटा में शामिल होने से बेहतर होंगे, लेकिन मुझे लगता है कि संग्रह किसी कारण से है)।


@haki टिप्पणी में उल्लेख किया है, आप भी कर सकते हैं:

... 
    select count(*) into c 
    from all_tables 
    where owner member of (i_itemname); 
... 

... जब तक i_name के रूप में और स्तंभ आप are the same type साथ तुलना कर रहे हैं। मेरे उदाहरण में यह शून्य पंक्तियां पाता है क्योंकि मैं की तुलना varchar2 से तुलना करने की कोशिश कर रहा हूं, लेकिन अगर i_name को varchar2(512) के रूप में फिर से परिभाषित किया गया तो एक मैच मिलेगा। आपके मामले में संभावित रूप से tab.colnvarchar2 वैसे भी है।

+2

+1 मुझे लगता है कि आप इसे 'e_itemname) के मालिक सदस्य जहां' e_itemname) 'के सभी चुनिंदा गिनती (*) से भी उपयोग कर सकते हैं। – haki

+0

@ हकी - अच्छा, मुझे नहीं लगता कि मैंने कभी इसका इस्तेमाल किया है। मेरे उदाहरण के लिए यह कोई मिलान नहीं पाता है [क्योंकि प्रकार मेल नहीं खाता है] (http://docs.oracle.com/cd/E11882_01/server.112/e26088/conditions006.htm#sthref1966) - मेरे पास 'i_type' है 'nvarchar2' लेकिन' मालिक' 'varchar2' है, लेकिन यह साफ है कि' i_type' मिलान करने के लिए फिर से परिभाषित किया गया है। (मैंने इसे अपने उत्तर में जोड़ा है, लेकिन यदि आप इसके साथ अपना जवाब पोस्ट करते हैं तो मैं इसे हटा दूंगा; क्रेडिट लेने की कोशिश नहीं कर रहा हूं!) –

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