2010-03-24 62 views
7

不幸的是,我的數據庫經驗大部分都與MSSQL有關,它比Oracle更傾向於您的手。我想要做的事情在tSQL中相當微不足道,但是,pl/sql讓我頭疼。從Oracle存儲過程中返回的XML

我有以下步驟:

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參數一個字符串並刪除「into」子句,查詢運行良好並返回預期的結構。

然而,當程序試圖執行查詢,XMLELEMENT函數的結果傳遞到USERRECORD輸出參數,我得到以下異常:

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沒有幫助。我發現了很多Oracle SQL | XML示例,但沒有一個處理XML從過程返回。

注意:我知道使用DBMS方法檢索XML的替代方法存在,但是,我的理解是,該功能已被棄用,以支持SQL | XML。

回答

10

您的代碼包含以下內容:

u.USERID = USERID; 

當你打算裸露USERID是過程的參數,實際上甲骨文優先選擇是在表中的列中的用戶ID。實際上它解釋爲

u.USERID = u.USERID; 

您可以使用

u.USERID = USPX_GetUserbyID.USERID; 

但它是使用PL/SQL變量的前綴,以避免混淆好的做法。我傾向於變量,i_,o_,io_用於輸入,輸出和輸入/輸出參數。

+0

謝謝!改變輸入參數完美。 – 2010-03-25 10:55:49

+0

好的。沒有看到。 – dacracot 2010-03-25 15:10:32

2

您的錯誤與XML無關。在PL/SQL中,如果您有一個返回多行的查詢,則必須使用遊標遍歷行。您已經使用了INTO關鍵字,它只能處理單個行(或您的案例中的XML)結果。

+0

這是我不明白。只有一個用戶記錄與查詢匹配。當我自己執行查詢時,Oracle SQL Developer中只返回一個XML行(我知道,這並不一定表示實際發生了什麼......) – 2010-03-24 23:17:50

0

您查詢顯然返回多個行。通過您構建過程的方式,您需要編寫查詢,以便返回包含所有XML的單個行。那麼你不應該收到錯誤。