2010-03-24 47 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的单个行。那么你不应该收到错误。