2015-10-16 9 views
10

एक लंबी कहानी कम करने के लिए मैं नीचे दिए गए कोड पर चर्चा करने का प्रस्ताव करता हूं।क्या ओरेकल 12 में एसक्यूएल में स्थानीय संग्रह प्रकारों में समस्याएं हैं?

इसे चलाने जब: "

:" 'PIPE_TABLE' के लिए गलत नंबर या कॉल में तर्क सुझावों के प्रकार PLS-00,306 "PLS

  • ओरेकल 11 संकलक

    को जन्म देती है -00642: स्थानीय संग्रह प्रकार एसक्यूएल स्टेटमेंट में अनुमत नहीं है "

  • ओरेकल 12 ऐसी कोई चेतावनी के साथ निम्नलिखित पैकेज संकलित है, लेकिन हम क्रम में एक आश्चर्य है

    जब गुमनाम ब्लॉक को क्रियान्वित करने के रूप में है - सब कुछ ठीक है (हम पाइप pipe_table समारोह में कुछ पंक्तियां सकता है - ऐसा नहीं 'टी को प्रभावित)

    अब

    के hello; के साथ लाइन uncomment या वहाँ किसी भी प्रक्रिया के लिए एक कॉल कर दिया, और फिर बदल anonumous ब्लॉक चलाने पर हम पाते हैं "ORA-22,163 करते हैं: बाएं हाथ और दाहिने हाथ की ओर संग्रह उसी के नहीं हैं टाइप करें "

और सवाल यह है: क्या ओरेकल 12 स्थानीय संग्रह प्रकारों को एसक्यूएल में अनुमति देता है? यदि हां तो PACKAGE buggy_report के कोड के साथ क्या गलत है?

CREATE OR REPLACE PACKAGE buggy_report IS 

    SUBTYPE t_id IS NUMBER(10); 
    TYPE t_id_table IS TABLE OF t_id; 

    TYPE t_info_rec IS RECORD (first NUMBER); 
    TYPE t_info_table IS TABLE OF t_info_rec; 
    TYPE t_info_cur IS REF CURSOR RETURN t_info_rec; 

    FUNCTION pipe_table(p t_id_table) RETURN t_info_table PIPELINED; 

    FUNCTION get_cursor RETURN t_info_cur; 

END buggy_report; 
/

CREATE OR REPLACE PACKAGE BODY buggy_report IS 

    FUNCTION pipe_table(p t_id_table) RETURN t_info_table PIPELINED IS 
    l_table t_id_table; 
    BEGIN 
     l_table := p; 
    END; 

    FUNCTION get_cursor RETURN t_info_cur IS 
    l_table t_id_table; 
    l_result t_info_cur; 
    BEGIN 

     OPEN l_result FOR SELECT * FROM TABLE (buggy_report.pipe_table(l_table)); 

     RETURN l_result; 
    END; 
END; 
/

DECLARE 
    l_cur buggy_report.t_info_cur; 
    l_rec l_cur%ROWTYPE; 
    PROCEDURE hello IS BEGIN NULL; END; 
BEGIN 

    l_cur := buggy_report.get_cursor(); 

    -- hello; 

    LOOP 
    FETCH l_cur INTO l_rec; 
    EXIT WHEN l_cur%NOTFOUND; 
    END LOOP; 

    CLOSE l_cur; 

    dbms_output.put_line('success'); 
END; 
/

उत्तर

0

आगे के प्रयोगों में हमने पाया कि समस्याएं मानी जाने से भी गहरी हैं।

उदाहरण के लिए, buggy_report पैकेज में उपयोग किए जाने वाले विभिन्न तत्वों को हम स्क्रिप्ट (प्रश्न में) चलाते समय ORA-03113: end-of-file on communication channel प्राप्त कर सकते हैं। यह t_id_tableVARRAY या TABLE .. INDEX BY .. के प्रकार को बदलने के साथ किया जा सकता है। कई अलग-अलग तरीकों और विविधताएं हैं जो हमें विभिन्न अपवादों तक ले जाती हैं, जो इस पोस्ट के विषय से बाहर हैं।

एक और दिलचस्प बात यह है कि buggy_report पैकेज विनिर्देश का संकलन समय 25 सेकंड तक ले सकता है, जब आमतौर पर इसमें लगभग 0.05 सेकंड लगते हैं। मैं निश्चित रूप से कह सकता हूं कि यह pipe_table फ़ंक्शन घोषणा में TYPE t_id_table पैरामीटर की उपस्थिति पर निर्भर करता है, और "लंबे समय संकलन" स्थापना मामलों के 40% में होता है। तो ऐसा लगता है कि local collection types in SQL के साथ समस्या संकलन के दौरान हाल ही में दिखाई देती है।

तो हम देखते हैं कि ओरेकल 12.1.0.2 स्पष्ट रूप से एसक्यूएल में स्थानीय संग्रह प्रकारों का उपयोग करने की प्राप्ति में एक बग है।

ORA-22163 और ORA-03113 प्राप्त करने के लिए न्यूनतम उदाहरण निम्न हैं। वहां हम सवाल के अनुसार buggy_report पैकेज मानते हैं।

-- produces 'ORA-03113: end-of-file on communication channel' 
DECLARE 
    l_cur buggy_report.t_info_cur; 

    FUNCTION get_it RETURN buggy_report.t_info_cur IS BEGIN RETURN buggy_report.get_cursor(); END;  
BEGIN 
    l_cur := get_it(); 

    dbms_output.put_line(''); 
END; 
/

-- produces 'ORA-22163: left hand and right hand side collections are not of same type' 
DECLARE 
    l_cur buggy_report.t_info_cur; 

    PROCEDURE hello IS BEGIN NULL; END; 
BEGIN 
    l_cur := buggy_report.get_cursor; 

    -- comment `hello` and exception disappears 
    hello; 

    CLOSE l_cur; 
END; 
/
+0

उदाहरणों में दो असामान्य ओरेकल विशेषताएं शामिल हैं - स्थानीय संग्रह और पाइपलाइन फ़ंक्शन। यह कहने के लिए मान्य हो सकता है "ओरेकल में पाइपलाइन कार्यों के साथ एक बग है"। मेरे अनुभव कार्यान्वयन में जो पाइपलाइन कार्यों का उपयोग करते हैं, वे आमतौर पर परेशानियों के लिए जा रहे हैं; या तो ओरेकल कीड़े या पंक्ति-दर-पंक्ति प्रसंस्करण की सीमाओं के कारण। –

0

हां, ओरेकल 12 सी में आपको स्थानीय संग्रह प्रकारों का उपयोग SQL में करने की अनुमति है।

प्रलेखन Database New Features Guide का कहना है:

PL/SQL विशिष्ट डेटा प्रकार PL/SQL-टू-एसक्यूएल इंटरफ़ेस

तालिका ऑपरेटर में अनुमति प्राप्त अब एक PL/SQL में इस्तेमाल किया जा सकता एक संग्रह पर कार्यक्रम जिसका डेटा प्रकार पीएल/एसक्यूएल में घोषित किया गया है। यह डेटा प्रकार को पीएल/एसक्यूएल एसोसिएटिव सरणी भी प्रदान करता है। (पूर्व रिलीज में, संग्रह का डेटा प्रकार स्कीमा स्तर पर घोषित किया जाना था।)

हालांकि, मुझे नहीं पता कि आपका कोड क्यों काम नहीं कर रहा है, शायद इस नई सुविधा में अभी भी एक बग है।

0

मैंने आपके उदाहरण के चारों ओर झुकाया। यह चाल है कि ओरेकल 12 सी एसक्यूएल कथन में पीएल/एसक्यूएल संग्रह का उपयोग कैसे कर सकता है यह है कि ओरेकल संगत एसक्यूएल प्रकार विशेषताओं के साथ सरोगेट स्कीमा ऑब्जेक्ट प्रकार बनाता है और इन सरोगेट प्रकारों को एक क्वेरी में उपयोग करता है। आपका मामला एक बग की तरह दिखता है। मैंने निष्पादन का पता लगाया और सरोगेट प्रकार केवल एक बार बनाए गए हैं यदि अस्तित्व में नहीं हैं। इसलिए पाइपलाइन किए गए फ़ंक्शन के निष्पादन के दौरान प्रभावी प्रकार बदलता नहीं है और न ही पुन: संकलित करता है (पता नहीं है कि एल्टर स्टेटमेंट का उपयोग करके अंतर्निहित पुनर्मूल्यांकन किया जाता है)। और समस्या तब होती है जब आप pipe_table फ़ंक्शन में p पैरामीटर का उपयोग करते हैं। यदि आप l_table := p; पर कॉल नहीं करते हैं तो कोड सक्षम विधि कॉल के साथ भी सफलतापूर्वक निष्पादित करता है।

+0

"समस्या केवल तब होती है जब आप पी पैरामीटर का उपयोग करते हैं" क्या आपका मतलब है "मैं पैरामीटर पी का उपयोग नहीं करूंगा"? सोचो, मैं इसे वहां क्यों पास कर सकता हूं - मैं इसका उपयोग करना चाहता था। 'पी' टेबल पर Iterating एक समस्या का सामना करना पड़ा (शायद आप भी इसे मिला है)। और यह assingnment 'l_table: = p; 'बस बग को पुन: उत्पन्न करने वाला न्यूनतम कोड है। अब मुझे दो चीजें पता हैं: 1. चाल के बिना उदाहरण v12.1.0.1 में घोषित "नई सुविधा" का सबसे सरल उपयोग दिखाता है; 2. कोड v12.1.0.2 पर भी अपेक्षित के रूप में काम नहीं करता है। मैं विश्वास करना चाहता हूं कि ओरेकल डेवलपर्स अपने कोड का परीक्षण मेरे मुकाबले ज्यादा कठिन हैं। तो ऐसा क्यों होता है? – diziaq

+0

नहीं, यह सिर्फ एक अवलोकन था। आप इसके बजाय स्कीमा प्रकार बना सकते हैं ('टाइप करें या टाइप करें t_id_table NUMBER (10)' तालिका है), तो ऐसा लगता है। – Husqvik

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