2016-12-20 4 views
1

내 테이블 열 중 하나에 저장된 XML 데이터에서 태그에 해당하는 데이터를 추출하는 데 도움이 필요합니다. 아래 표는 샘플 XML 데이터이며 'REQUESTTYPE'태그에 해당하는 값을 추출해야합니다.오라클의 xml 데이터에서 값 추출

<?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

위의 XML에 대해 'ADD'를 반환하는 쿼리를 찾고 있습니다. 내 테이블 xml 열 및 다른 몇 가지 날짜 특성 위에 있습니다. – AsteriK

답변

1

EXTRACTVALUE 기능은 더 이상 사용되지 않습니다. 이전 버전과의 호환성을 위해 계속 지원됩니다. 그러나 오라클은 대신 XMLTABLE 함수 또는 XMLCAST 및 XMLQUERY 함수를 사용할 것을 권장합니다. 자세한 내용은 XMLTABLE, XMLCAST 및 XMLQUERY를 참조 잘 작동 xmltableEXTRACTVALUE

함수를 참조하십시오, 당신은 또한 사용할 수 있습니다 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

감사합니다. Rene, 위의 블록이 작동합니다! 테이블에서 xml 데이터를 직접 읽고 원하는 출력을 얻는 데 사용할 수있는 단일 행 쿼리가 있습니까? 내가 where 절을 만족시키는 테이블의 여러 레코드에 대해이 작업을 수행해야하기 때문에 내가 묻는 이유가 있습니다. – AsteriK

+0

간단히'xmltype()'을 대체하십시오. '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' 만 사용할 수 있습니다. 데이터 타입이 VARCHAR2 또는 CLOB 인 경우 'xmltype (XML_DATA)'가 필요합니다 –

+0

예 @Wernfried Domscheit, 테이블의 XML_DATA가 CLOB 데이터 유형입니다 – AsteriK