2010-03-24 14 views
7

दुर्भाग्यवश मेरा अधिकांश डीबी अनुभव एमएसएसएलएल के साथ रहा है जो आपके हाथ को ओरेकल से बहुत अधिक पकड़ता है। मैं जो करने की कोशिश कर रहा हूं वह टीएसक्यूएल में काफी छोटा है, हालांकि, pl/sql मुझे सिरदर्द दे रहा है।ओरेकल संग्रहीत प्रक्रिया से एक्सएमएल रिटर्न

CREATE OR REPLACE PROCEDURE USPX_GetUserbyID (USERID USERS.USERID%TYPE, USERRECORD OUT XMLTYPE) AS 
BEGIN 

    SELECT XMLELEMENT("user" 
     , XMLATTRIBUTES(u.USERID AS "userid", u.companyid as "companyid", u.usertype as "usertype", u.status as "status", u.personid as "personid") 
     , XMLFOREST( p.FIRSTNAME AS "firstname" 
        , p.LASTNAME AS "lastname" 
        , p.EMAIL AS "email" 
        , p.PHONE AS "phone" 
        , p.PHONEEXTENSION AS "extension") 
     , XMLELEMENT("roles", 
       (SELECT XMLAGG(XMLELEMENT("role", r.ROLETYPE)) 
        FROM USER_ROLES r 
        WHERE r.USERID = USERID 
         AND r.ISACTIVE = 1 
       ) 
      ) 
     , XMLELEMENT("watches", 
       (SELECT XMLAGG(
        XMLELEMENT("watch", 
         XMLATTRIBUTES(w.WATCHID AS "id", w.TICKETID AS "ticket") 
        ) 
       ) 
       FROM USER_WATCHES w 
       WHERE w.USERID = USERID 
       AND w.ISACTIVE = 1 
       ) 
      ) 
     ) AS "RESULT" 
    INTO USERRECORD 
    FROM USERS u 
    LEFT JOIN PEOPLE p ON p.PERSONID = u.PERSONID 
    WHERE u.USERID = USERID; 
    END USPX_GetUserbyID; 

जब मार डाला, यह निम्न संरचना के साथ XML दस्तावेज़ चाहिए::

मैं निम्नलिखित प्रक्रिया है

<user userid="" companyid="" usertype="" status="" personid=""> 
    <firstname /> 
    <lastname /> 
    <email /> 
    <phone /> 
    <extension /> 
    <roles> 
     <role /> 
    </roles> 
    <watches> 
     <watch id="" ticket="" /> 
    </watches> 
</user> 

जब मैं स्वयं क्वेरी निष्पादित, साथ USERID पैरामीटर की जगह एक स्ट्रिंग और "इन" खंड को हटाकर, क्वेरी ठीक चलती है और अपेक्षित संरचना लौटाती है।

हालांकि, जब प्रक्रिया क्वेरी निष्पादित करने के लिए, USERRECORD उत्पादन पैरामीटर में XmlElement समारोह के परिणाम गुजर प्रयास करता है, मैं निम्नलिखित अपवाद:

Error report: ORA-01422: exact fetch returns more than requested number of rows ORA-06512: at "USPX_GETUSERBYID", line 4 ORA-06512: at line 3 
01422. 00000 - "exact fetch returns more than requested number of rows" 
*Cause: The number specified in exact fetch is less than the rows returned. 
*Action: Rewrite the query or change number of rows requested 

मैं इस जकड़ना करने की कोशिश कर रहा हूँ को विस्मित कर , और दुर्भाग्य से मेरे google-fu ने मदद नहीं की है। मुझे बहुत सारे ओरेकल एसक्यूएल | एक्सएमएल उदाहरण मिले हैं, लेकिन कोई भी प्रक्रिया जो एक्सएमएल रिटर्न से किसी प्रक्रिया से नहीं है।

नोट: मुझे पता है कि डीबीएमएस तरीकों का उपयोग कर एक्सएमएल पुन: प्राप्त करने का एक वैकल्पिक तरीका मौजूद है, तथापि, यह मेरी समझ है कि है कि कार्यक्षमता एसक्यूएल के पक्ष में पदावनत कर रहा है | एक्सएमएल।

उत्तर

10

आपका कोड में निम्नलिखित शामिल हैं। अपने आपमें यह यह व्याख्या के रूप में

u.USERID = u.USERID; 

आप

u.USERID = USPX_GetUserbyID.USERID; 

उपयोग कर सकते हैं, लेकिन यह PL/SQL चर के लिए एक उपसर्ग का उपयोग करने के भ्रम से बचने के अच्छी आदत है। मैं इनपुट, आउटपुट और इनपुट/आउटपुट पैरामीटर के लिए चर के लिए v_ और i_, o_, io_ की ओर जाता हूं।

+0

धन्यवाद! इनपुट पैरामीटर बदलना पूरी तरह से काम करता है। –

+0

अच्छा पकड़ो। उसे नहीं देखा। – dacracot

2

आपकी त्रुटि में XML के साथ कुछ लेना देना नहीं है। पीएल/एसक्यूएल में यदि आपके पास एक क्वेरी है जो एकाधिक पंक्तियां लौटाती है, तो आपको कर्सर के साथ पंक्तियों के माध्यम से लूप करना होगा। आपने INTO कीवर्ड का उपयोग किया है जो केवल एक पंक्ति (या आपके मामले में एक्सएमएल) परिणाम संभाल सकता है।

u.USERID = USERID; 

आप नंगे USERID इरादा जबकि प्रक्रिया के पैरामीटर होने के लिए, ओरेकल वास्तव में वरीयता USERID सारणी में स्तंभ है कि करने के लिए देता है:

+0

यही वह है जिसे मैं समझ नहीं पा रहा हूं। केवल एक ही उपयोगकर्ता रिकॉर्ड है जो क्वेरी से मेल खाता है। जब मैं स्वयं क्वेरी को निष्पादित करता हूं, ओरेकल एसक्यूएल डेवलपर में केवल एक ही एक्सएमएल पंक्ति लौटा दी जाती है (जो मुझे पता है, वास्तव में क्या हो रहा है इसका एक संकेत नहीं है ...) –

0

आप क्वेरी एक स्पष्ट रूप से एक से अधिक पंक्तियों को लौट रहे हैं। जिस तरह से आपने अपनी प्रक्रिया को संरचित किया है, आपको अपनी क्वेरी को इस तरह से लिखना होगा कि यह एक ही पंक्ति को लौटाए जिसमें सभी एक्सएमएल शामिल हैं। तब आपको त्रुटि प्राप्त नहीं करनी चाहिए।

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