2012-06-25 6 views
8

नीचे W.r.t कोड मैं अंतर्निहित तालिका के% ROWTYPE के रूप में fetch-in-variable के प्रकार की घोषणा नहीं कर सकता क्योंकि SYS_REFCURSOR एक चयन पर है जो दो तालिकाओं में शामिल होता है और अंतर्निहित दो तालिकाओं के गुणों पर बुलाए गए कुछ फ़ंक्शंस भी चुनता है; यानी मैं L_RECORD टी% ROWTYPEएक परिवर्तनीय के% ROWTYPE को कैसे घोषित किया जाए जो कमजोर टाइप किए गए SYS_REFCURSOR है?

--- 
DECLARE 
    P_RS SYS_REFCURSOR; 
    L_RECORD P_RS%ROWTYPE; 
BEGIN 
    CAPITALEXTRACT(
    P_RS => P_RS 
); 
    OPEN P_RS; 
    LOOP 
     BEGIN 
     FETCH P_RS INTO L_RECORD; 
     EXIT WHEN P_RS%NOTFOUND; 
     ... 
     EXCEPTION 
     WHEN OTHERS THEN 
     ... 
     END; 
    END LOOP; 
    CLOSE P_RS; 
END; 
-------- 
CREATE or REPLACE PROCEDURE CAPITALEXTRACT 
(
    p_rs OUT SYS_REFCURSOR 
) AS 
BEGIN 
    OPEN p_rs for 
    select t.*,tminusone.*, f(t.cash), g(t.cash) FROM T t, TMINUSONE tminusone 
    where t.ticket=tminusone.ticket; 
END CAPITALEXTRACT; 
बेशक

मैं के रूप में SYS_REFCURSOR में लौट आए कॉलम के साथ एक स्थिर तालिका आर परिभाषित और फिर L_RECORD आर% ROWTYPE के रूप में घोषित करने के लिए नहीं करना चाहते हैं के रूप में घोषित नहीं कर सकते।

और इसलिए प्रश्न: एक कमजोर टाइप किए गए SYS_REFCURSOR की चर के% ROWTYPE को कैसे घोषित किया जाए?

उत्तर

14

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

DECLARE 
    P_RS SYS_REFCURSOR; 
    L_T_COL1 T.COL1%TYPE; 
    L_T_COL1 T.COL2%TYPE; 
    ... 

और फिर स्तंभों की सूची में लाने:

FETCH P_RS INTO L_T_COL1, L_T_COL2, ... ; 

इस के रूप में आप जानते हैं कि आप रेफरी कर्सर में उम्मीद कर रहे हैं दर्दनाक लेकिन लंबे समय के रूप प्रबंधनीय है। आपकी प्रक्रिया में T.* का उपयोग करना इस नाजुक बनाता है, क्योंकि तालिका में एक कॉलम जोड़ना कोड को तोड़ देगा जो सोचता है कि यह जानता है कि कॉलम क्या हैं और वे किस क्रम में हैं। (यदि आप तालिकाएं हैं तो आप पर्यावरण के बीच भी इसे तोड़ सकते हैं ' टी लगातार बनाए गए - मैंने उन स्थानों को देखा है जहां विभिन्न वातावरण में कॉलम ऑर्डरिंग अलग है)। आप संभवतः यह सुनिश्चित करना चाहते हैं कि आप केवल उन्हीं कॉलम का चयन कर रहे हैं जिनकी आप वास्तव में परवाह करते हैं, उन चीजों के लिए चर परिभाषित करने से बचने के लिए जिन्हें आप कभी नहीं पढ़ेंगे।

11g से आप DBMS_SQL पैकेज का उपयोग अपने sys_refcursor एक DBMS_SQL कर्सर में तब्दील कर सकते हैं, और आप पूछताछ कर सकते हैं, जो स्तंभ निर्धारित करने के लिए। बस आप क्या कर सकते का एक उदाहरण के रूप में, यह प्रत्येक पंक्ति में प्रत्येक स्तंभ के मूल्य बाहर प्रिंट होगा, स्तंभ नाम के साथ:

DECLARE 
    P_RS SYS_REFCURSOR; 
    L_COLS NUMBER; 
    L_DESC DBMS_SQL.DESC_TAB; 
    L_CURS INTEGER; 
    L_VARCHAR VARCHAR2(4000); 
BEGIN 
    CAPITALEXTRACT(P_RS => P_RS); 
    L_CURS := DBMS_SQL.TO_CURSOR_NUMBER(P_RS); 
    DBMS_SQL.DESCRIBE_COLUMNS(C => L_CURS, COL_CNT => L_COLS, 
     DESC_T => L_DESC); 

    FOR i IN 1..L_COLS LOOP 
     DBMS_SQL.DEFINE_COLUMN(L_CURS, i, L_VARCHAR, 4000); 
    END LOOP; 

    WHILE DBMS_SQL.FETCH_ROWS(L_CURS) > 0 LOOP 
     FOR i IN 1..L_COLS LOOP 
      DBMS_SQL.COLUMN_VALUE(L_CURS, i, L_VARCHAR); 
      DBMS_OUTPUT.PUT_LINE('Row ' || DBMS_SQL.LAST_ROW_COUNT 
       || ': ' || l_desc(i).col_name 
       || ' = ' || L_VARCHAR); 
     END LOOP; 
    END LOOP; 

    DBMS_SQL.CLOSE_CURSOR(L_CURS); 
END; 
/

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

यदि आप केवल अपने रेफ कर्सर से कुछ कॉलम चाहते हैं, तो मुझे लगता है कि l_desc के आसपास लूप करें और उस स्थिति को रिकॉर्ड करें जहां column_name जो भी आप रुचि रखते हैं, एक संख्यात्मक चर के रूप में; फिर आप बाद में उस चर द्वारा कॉलम का संदर्भ ले सकते हैं जहां आप आमतौर पर कर्सर लूप में नाम का उपयोग करेंगे। निर्भर करता है कि आप डेटा के साथ क्या कर रहे हैं।

लेकिन जब तक आप उम्मीद स्तंभ क्रम तुम वापस हो रही है, जो की संभावना नहीं है पता नहीं है क्योंकि आप प्रक्रिया को नियंत्रित करने के लग रहे हैं - और यह सोचते हैं आप .* रों से छुटकारा पाने के - आप शायद ज्यादा कर रहे हैं लौटे कॉलम को कम से कम कम करने के लिए बेहतर करना और उन्हें सभी को अलग-अलग घोषित करना बेहतर है।

+0

बहुत बढ़िया आदमी, मैं एक साल की तलाश कर रहा हूं कि यह कैसे करें और इससे यह सबसे अच्छा समझाया गया। नोट: मुझे CAPITALEXTRACT (P_RS => P_RS) की आवश्यकता नहीं थी; लाइन। (वास्तव में यह गलती से, यह सुनिश्चित नहीं था कि उसने क्या किया है इसलिए मैंने टिप्पणी की और मेरा pl/sql फिर शानदार ढंग से भाग गया) – armyofda12mnkeys

+0

@ armyofda12mnkeys - खुशी हुई इससे मदद मिली। CAPITALEXTRACT इस प्रश्न के लिए विशिष्ट कार्य था, समाधान के लिए आंतरिक कुछ नहीं, इसलिए इसके बारे में चिंता न करें। –

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