2011-12-19 11 views
5

how to return a dynamic result set in Oracle functionOracle SQL एक समारोह बनाने - त्रुटियों

मैं एक समारोह है कि कई तालिकाओं से कई मायने रखता है के साथ एक पंक्ति वापस आ जाएगी बनाने के लिए कोशिश कर रहा हूँ के आधार पर संकलित भ्रमित। यहाँ मैं अब तक है:

CREATE OR REPLACE TYPE RESULT_ROW is OBJECT 
(LOC_TABLE_ENTRY_KY VARCHAR2(50), 
LOCATION_NAME VARCHAR2(50), 
A_ASSIGN_CNT VARCHAR2(50), 
B_ASSIGN_CNT VARCHAR2(50), 
C_ASSIGN_CNT VARCHAR2(50), 
D_ASSIGN_CNT VARCHAR2(50), 
E_ASSIGN_CNT VARCHAR2(50), 
F_ASSIGN_CNT VARCHAR2(50), 
G_ASSIGN_CNT VARCHAR2(50), 
H_ASSIGN_CNT VARCHAR2(50)); 
/
CREATE OR REPLACE TYPE RESULT_TABLE AS TABLE OF RESULT_ROW; 
/
CREATE OR REPLACE FUNCTION LOCATION_RULE_LOOKUP(P_LOCATION_VAR IN NUMBER) 
RETURN RESULT_TABLE 
IS 
OUT_REC RESULT_TABLE; 
BEGIN 
WITH LOC AS 
(SELECT LOC_TABLE_ENTRY_KY, 
LOCATION_NAME 
FROM LOCATION_CODE 
WHERE LOC_TABLE_ENTRY_KY = P_LOCATION_VAR 
), 
ONE AS 
(SELECT COUNT(*) AS A_ASSIGN_CNT 
FROM COLLECTOR_ASSIGNMENT 
WHERE LOCATION_CODE  = P_LOCATION_VAR 
AND FUNCTION_STATE_CODE = ' ' 
OR FUNCTION_STATE_CODE = '***' 
), 
TWO AS 
(SELECT COUNT(*) AS B_ASSIGN_CNT 
FROM COMM_PLAN_ASSGN_RULE 
WHERE LOCATION_CODE = P_LOCATION_VAR 
), 
THREE AS 
(SELECT COUNT(*) AS C_ASSIGN_CNT 
FROM INPUT_TRANS_ASGN 
WHERE LOCATION_CODE = P_LOCATION_VAR 
), 
FOUR AS 
(SELECT COUNT(*) AS D_ASSIGN_CNT 
FROM RECALL_DAYS_ASSGN_RULE 
WHERE LOCATION_CODE = P_LOCATION_VAR 
), 
FIVE AS 
(SELECT COUNT(*) AS E_ASSIGN_CNT 
FROM SCRIPT_VIEW_ASSIGNMENT 
WHERE LOCATION_CODE  = P_LOCATION_VAR 
AND FUNCTION_STATE_CODE = ' ' 
OR FUNCTION_STATE_CODE = '***' 
AND SCRIPT_TYPE   = 'V' 
), 
SIX AS 
(SELECT COUNT(*) AS F_ASSIGN_CNT 
FROM SCRIPT_VIEW_ASSIGNMENT 
WHERE LOCATION_CODE  = P_LOCATION_VAR 
AND FUNCTION_STATE_CODE = ' ' 
OR FUNCTION_STATE_CODE = '***' 
AND SCRIPT_TYPE   = 'D' 
), 
SEVEN AS 
(SELECT COUNT(*) AS G_ASSIGN_CNT 
FROM TSR_ASSGN_RULE 
WHERE LOCATION_CODE = P_LOCATION_VAR 
), 
EIGHT AS 
(SELECT COUNT(*) AS H_ASSIGN_CNT 
FROM TRAN_STATE_ASSGN_RULE 
WHERE LOCATION_CODE = P_LOCATION_VAR 
) 
SELECT * INTO OUT_REC 
FROM ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, LOC; 
RETURN OUT_REC; 
END LOCATION_RULE_LOOKUP; 

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

Error(7,3): PL/SQL: SQL Statement ignored 
Error(62,3): PL/SQL: ORA-00947: not enough values 

सहायता? डी:

उत्तर

6

आप बहुत करीब हैं, लेकिन आपने लिंक किए गए प्रश्न काफी ईमानदारी से पर्याप्त नहीं किया है। not enough values संदेश का कारण यह है कि आपके पास केवल INTO खंड में एक मान है, लेकिन ओरेकल आपको आठ होने की उम्मीद कर रहा है, क्योंकि यह आपके SELECT * में कितने अभिव्यक्ति (प्रभावी रूप से) हैं। आपको उन आठ अभिव्यक्तियों को एक ही मूल्य में डालना होगा। ऐसा करने के लिए, आपको अपनी WITH ... SELECT * INTO out_rec ... को SELECT CAST(MULTISET(WITH ... SELECT * ...) AS result_table) INTO out_rec FROM dual या WITH ... SELECT CAST(MULTISET(SELECT * ...) AS result_table) INTO out_rec FROM dual में बदलना होगा, जैसा आप चाहें।

इसके अलावा, आप LOC पूर्ववर्ती EIGHT के माध्यम से ONE साथ, सही क्रम में अपने FROM खंड डाल करने के लिए की जरूरत है; कास्ट क्षेत्र के उपनामों के आधार पर अभिव्यक्तियों की सापेक्ष स्थिति, पर आधारित नहीं किया जाता है। (वैकल्पिक रूप से, आप अपने SELECT * स्पष्ट रूप से क्षेत्रों की पहचान करने के सही क्रम में नहीं बल्कि FROM -clause आदेश पर भरोसा करने की बजाय बदल सकता है,,।)

+0

हे, यही वह चीज़ है जो मुझे समझ में नहीं आता है। आपको परेशान करने के लिए माफी चाहता हूं। वे मुद्दे वास्तव में थे - अब काम करता है। :) –

+0

माफी माँगने की कोई ज़रूरत नहीं है। मुझे खुशी है कि यह आपके लिए काम कर रहा है। :-) – ruakh

4

@ शामिल CAST और MULTISET वास्तव में और अधिक जटिल की तुलना में यह करने की जरूरत है ruakh के जवाब । आप एक संग्रह वापस जाने के लिए RESULT_ROW के लिए डिफ़ॉल्ट निर्माता का उपयोग करने के लिए और आदेश में BULK COLLECT उपयोग करने की आवश्यकता:

CREATE OR REPLACE TYPE result_row IS OBJECT 
    (loc_table_entry_ky VARCHAR2(50), 
    location_name VARCHAR2(50), 
    a_assign_cnt VARCHAR2(50), 
    b_assign_cnt VARCHAR2(50), 
    c_assign_cnt VARCHAR2(50), 
    d_assign_cnt VARCHAR2(50), 
    e_assign_cnt VARCHAR2(50), 
    f_assign_cnt VARCHAR2(50), 
    g_assign_cnt VARCHAR2(50), 
    h_assign_cnt VARCHAR2(50)); 
/

CREATE OR REPLACE TYPE result_table AS TABLE OF result_row; 
/

CREATE OR REPLACE FUNCTION location_rule_lookup(p_location_var IN NUMBER) 
    RETURN result_table IS 
    out_rec result_table; 
BEGIN 
    WITH loc AS (SELECT 'blarg' AS loc_table_entry_ky, 'foo' AS location_name FROM DUAL), 
     one AS (SELECT COUNT(*) AS a_assign_cnt FROM DUAL), 
     two AS (SELECT COUNT(*) AS b_assign_cnt FROM DUAL), 
     three AS (SELECT COUNT(*) AS c_assign_cnt FROM DUAL), 
     four AS (SELECT COUNT(*) AS d_assign_cnt FROM DUAL), 
     five AS (SELECT COUNT(*) AS e_assign_cnt FROM DUAL), 
     six AS (SELECT COUNT(*) AS f_assign_cnt FROM DUAL), 
     seven AS (SELECT COUNT(*) AS g_assign_cnt FROM DUAL), 
     eight AS (SELECT COUNT(*) AS h_assign_cnt FROM DUAL) 
    SELECT result_row(loc_table_entry_ky, 
        location_name, 
        a_assign_cnt, 
        b_assign_cnt, 
        c_assign_cnt, 
        d_assign_cnt, 
        e_assign_cnt, 
        f_assign_cnt, 
        g_assign_cnt, 
        h_assign_cnt) 
    BULK COLLECT INTO out_rec 
    FROM one, 
      two, 
      three, 
      four, 
      five, 
      six, 
      seven, 
      eight, 
      loc; 
    RETURN out_rec; 
END location_rule_lookup; 
/

(जाहिर है, इस एक सरलीकृत संस्करण है मैं अपने टेबल की जरूरत नहीं है के रूप में, मैं dual प्रतिस्थापन का सहारा लिया। उनके स्थान पर।)

+0

+1। काफी हद तक, जिस तरह से आप वर्णन करते हैं वह वास्तव में कम या कम है, मैं इसे अपने कोड में कैसे करता हूं (केवल आज सुबह!); एकमात्र कारण मैं 'सीएएसटी (मल्टीसेट (...) एएस के साथ गया ...)' यह है कि ओपी उस उदाहरण का पालन करने की कोशिश कर रहा था जिसने उस दृष्टिकोण का उपयोग किया था। – ruakh

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