2016-12-20 6 views
1

Мне нужна помощь по извлечению данных, соответствующих тегу из данных xml, хранящихся в одном из столбцов таблицы. Ниже приведен пример XML-данных в моей таблице, и мне нужно извлечь значение, соответствующее тегу «REQUESTTYPE».Извлечение значения из данных xml в Oracle

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE VXIN SYSTEM "VXInData.dtd"> 
<VXIN> 
<REQUESTS> 
<REQUEST> 
<REQUESTTYPE>ADD</REQUESTTYPE> 
<REQUESTNUMBER>12345</REQUESTNUMBER> 
<ID>1234567</ID> 
<ACCESSLIST> 
<ACCESS> 
<ACCESSLEVEL> 
<AID>123789</AID> 
</ACCESSLEVEL> 
<PERSONNEL> 
<REQUESTEDFOR> 
<UID>13579</UID> 
<FIRSTNAME>MOBY</FIRSTNAME> 
</REQUESTEDFOR> 
</PERSONNEL> 
</ACCESS> 
</ACCESSLIST> 
</REQUEST> 
</REQUESTS> 
</VXIN> 

Любая помощь очень ценится.

+0

ПОЖАЛУЙСТА, покажите, каков ваш ожидаемый результат, определение схемы таблицы. – OldProgrammer

+0

Я думаю, что это очень хорошо. – Rene

+0

Я ищу запрос, который возвращает 'ADD' для вышеуказанного xml. Моя таблица имеет столбец xml и несколько других атрибутов даты. – AsteriK

ответ

1

Функция EXTRACTVALUE устарела. Он по-прежнему поддерживается для обратной совместимости. Однако Oracle рекомендует использовать функцию XMLTABLE или функции XMLCAST и XMLQUERY. См XMLTABLE, XMLCAST и XMLQUERY для получения дополнительной информации см EXTRACTVALUE

Функция xmltable работает нормально, вы можете также использовать XMLQUERY:

SELECT XMLQUERY('/VXIN/REQUESTS/REQUEST/REQUESTTYPE/text()' 
    PASSING XMLTYPE('<?xml version="1.0" encoding="UTF-8"?> 
<VXIN> 
<REQUESTS> 
<REQUEST> 
<REQUESTTYPE>ADD</REQUESTTYPE> 
<REQUESTNUMBER>12345</REQUESTNUMBER> 
<ID>1234567</ID> 
<ACCESSLIST> 
<ACCESS> 
<ACCESSLEVEL> 
<AID>123789</AID> 
</ACCESSLEVEL> 
<PERSONNEL> 
<REQUESTEDFOR> 
<UID>13579</UID> 
<FIRSTNAME>MOBY</FIRSTNAME> 
</REQUESTEDFOR> 
</PERSONNEL> 
</ACCESS> 
</ACCESSLIST> 
</REQUEST> 
</REQUESTS> 
</VXIN>') RETURNING CONTENT) AS REQUESTTYPE 
FROM dual; 

Однако, в случае, если вы хотите, чтобы извлечь больше, чем просто одно значение XMLTABLE () должен быть лучше.

+0

Спасибо Wernfried, выше решение работало отлично! – AsteriK

2

Один из способов сделать это:

declare 
    l_xml   xmltype; 
    l_requesttype varchar2(30); 
begin 
    l_xml := xmltype('<?xml version="1.0" encoding="UTF-8"?> 
<VXIN> 
<REQUESTS> 
<REQUEST> 
<REQUESTTYPE>ADD</REQUESTTYPE> 
<REQUESTNUMBER>12345</REQUESTNUMBER> 
<ID>1234567</ID> 
<ACCESSLIST> 
<ACCESS> 
<ACCESSLEVEL> 
<AID>123789</AID> 
</ACCESSLEVEL> 
<PERSONNEL> 
<REQUESTEDFOR> 
<UID>13579</UID> 
<FIRSTNAME>MOBY</FIRSTNAME> 
</REQUESTEDFOR> 
</PERSONNEL> 
</ACCESS> 
</ACCESSLIST> 
</REQUEST> 
</REQUESTS> 
</VXIN>'); 

    select x.* 
    into l_requesttype 
    from xmltable('/VXIN/REQUESTS/REQUEST' passing l_xml columns requesttype varchar2(30) path 'REQUESTTYPE') x; 

    dbms_output.put_line(l_requesttype); 
end; 

Как вы можете видеть, я удалил ссылку на DTD, так как база данных не может получить к нему доступ. Чтобы запустить этот код с помощью ссылки DTD, вы можете заставить анализатор не искать его.

declare 
    l_xml   xmltype; 
    l_requesttype varchar2(30); 
begin 

    execute immediate 'alter session set events =''31156 trace name context forever, level 2'''; 

    l_xml := xmltype('<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE VXIN SYSTEM "VXInData.dtd"> 
<VXIN> 
<REQUESTS> 
<REQUEST> 
<REQUESTTYPE>ADD</REQUESTTYPE> 
<REQUESTNUMBER>12345</REQUESTNUMBER> 
<ID>1234567</ID> 
<ACCESSLIST> 
<ACCESS> 
<ACCESSLEVEL> 
<AID>123789</AID> 
</ACCESSLEVEL> 
<PERSONNEL> 
<REQUESTEDFOR> 
<UID>13579</UID> 
<FIRSTNAME>MOBY</FIRSTNAME> 
</REQUESTEDFOR> 
</PERSONNEL> 
</ACCESS> 
</ACCESSLIST> 
</REQUEST> 
</REQUESTS> 
</VXIN>'); 

    select x.* 
    into l_requesttype 
    from xmltable('/VXIN/REQUESTS/REQUEST' passing l_xml columns requesttype varchar2(30) path 
        'REQUESTTYPE') x; 

    dbms_output.put_line(l_requesttype); 
end; 
+0

Спасибо, Рен, этот блок работает! Есть ли один запрос строки, который я мог бы использовать для прямого чтения xml-данных из таблицы и получения желаемого результата. Причина, по которой я спрашиваю, заключается в том, что мне нужно будет выполнить эту операцию для нескольких записей в таблице, в зависимости от того, что удовлетворяет моему предложению where. – AsteriK

+0

Просто замените 'xmltype()', resp. 'l_xml' с вашим именем столбца. –

0

Основываясь на решении, опубликованном Wernfried, я немного настроил запрос для чтения значений из моей таблицы. Ниже мой окончательный запрос:

select XMLQUERY('/VXIN/REQUESTS/REQUEST/REQUESTTYPE/text()' passing xmltype(XML_DATA) RETURNING CONTENT) AS REQUESTTYPE from table; 
+0

Каков тип данных столбца 'XML_DATA'? В случае 'XMLTYPE' вам не нужно создавать' xmltype (XML_DATA) ', вы можете просто использовать' XML_DATA'. 'xmltype (XML_DATA)' будет требоваться, если тип данных VARCHAR2 или CLOB –

+0

Да @Wernfried Domscheit, XML_DATA в моей таблице имеет тип данных CLOB – AsteriK

 Смежные вопросы

  • Нет связанных вопросов^_^