【问题标题】:XML Return from an Oracle Stored Procedure从 Oracle 存储过程返回 XML
【发布时间】:2011-01-31 12:09:11
【问题描述】:

不幸的是,我的大部分 DB 经验都是使用 MSSQL,它比 Oracle 更容易掌握你的手。我正在尝试做的事情在 tSQL 中是相当微不足道的,但是 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 参数替换为字符串并删除“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。

【问题讨论】:

    标签: xml oracle stored-procedures plsql


    【解决方案1】:

    您的代码包括以下内容:

    u.USERID = USERID;
    

    虽然您打算将裸露的 USERID 作为过程的参数,但 Oracle 实际上优先考虑作为表中的列的 USERID。实际上,它将其解释为

    u.USERID = u.USERID;
    

    你可以使用

    u.USERID = USPX_GetUserbyID.USERID;
    

    但最好为 PL/SQL 变量使用前缀以避免混淆。我倾向于 v_ 用于变量,i_、o_、io_ 用于输入、输出和输入/输出参数。

    【讨论】:

    • 不错的收获。没看到。
    【解决方案2】:

    您的错误与 XML 无关。在 PL/SQL 中,如果您有一个返回多行的查询,则必须使用游标遍历这些行。您使用了 INTO 关键字,它只能处理单行(或在您的情况下为 XML)结果。

    【讨论】:

    • 这是我不明白的。只有一条用户记录与查询匹配。当我执行查询本身时,Oracle SQL Developer 中只返回一个 XML 行(我知道,这不一定表明实际发生了什么......)
    【解决方案3】:

    您的查询显然返回不止一行。使用您构建过程的方式,您需要以返回包含所有 XML 的单行的方式编写查询。那么您应该不会收到错误消息。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-11-03
      • 1970-01-01
      • 2017-05-07
      • 2019-06-03
      • 2014-08-31
      • 1970-01-01
      • 2012-01-04
      相关资源
      最近更新 更多