Возврат XML из хранимой процедуры Oracle - PullRequest
7 голосов
/ 25 марта 2010

К сожалению, большая часть моего опыта работы с БД была связана с 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

Я сбит с толку, пытаясь зафиксировать это, и, к сожалению, мой гугл-фу не помог. Я нашел множество примеров Oracle SQL | XML, но ни один из них, касающийся XML, не возвращается из процедуры.

Примечание: Я знаю, что существует альтернативный метод извлечения XML с использованием методов СУБД, однако, насколько я понимаю, эта функциональность устарела в пользу SQL | XML.

Ответы [ 3 ]

10 голосов
/ 25 марта 2010

Ваш код включает в себя следующее:

u.USERID = USERID;

В то время как вы намерены указывать в качестве параметра процедуры пустой USERID, Oracle фактически отдает предпочтение USERID, который является столбцом таблицы. В действительности это интерпретирует это как

u.USERID = u.USERID;

Вы можете использовать

u.USERID = USPX_GetUserbyID.USERID;

но хорошей практикой является использование префикса для переменных PL / SQL, чтобы избежать путаницы. Я склоняюсь к v_ для переменных и i_, o_, io_ для параметров ввода, вывода и ввода / вывода.

2 голосов
/ 25 марта 2010

Ваша ошибка не имеет ничего общего с XML. В PL / SQL, если у вас есть запрос, который возвращает несколько строк, вы должны перебирать строки курсором. Вы использовали ключевое слово INTO, которое может обрабатывать только одну строку (или XML в вашем случае).

0 голосов
/ 25 марта 2010

Ваш запрос, по-видимому, возвращает более одной строки. При том, как вы структурировали свою процедуру, вам нужно написать свой запрос таким образом, чтобы он возвращал одну строку, содержащую весь XML. Тогда вы не должны получить ошибку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...