2015-01-29 17 views
2

CLOB 데이터 유형 인 RESPONSE_XML 컬럼이있는 SOAP_MONITORING 테이블이 있습니다. 이 열에는 큰 xml 문자열이 저장됩니다. 이 XML 문자열에서 노드 이름과 노드 값을 가져 오려고합니다. 내가 201501070917439804SUBSCRIPTION_ID을 얻기 위해이 열을 조회 할Oracle SQL 쿼리를 사용하여 XML에서 특정 노드 이름과 해당 값을 선택하는 방법은 무엇입니까?

<?xml version='1.0' encoding='utf-8'?> 
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><ns:placeShopOrderResponse xmlns:ns="http://service.soap.CDRator.com"> 
<ns:return xmlns:ax2133="http://signup.data.soap.CDRator.com/xsd" xmlns:ax2134="http://core.signup.data.soap.CDRator.com/xsd" xmlns:ax2127="http://data.soap.CDRator.com/xsd" xmlns:ax2129="http://webshop.data.soap.CDRator.com/xsd" xmlns:ax2130="http://core.data.soap.CDRator.com/xsd" xmlns:ax2140="http://core.result.service.soap.CDRator.com/xsd" xmlns:ax2139="http://result.service.soap.CDRator.com/xsd" xmlns:ax2147="http://webshop.result.service.soap.CDRator.com/xsd" xmlns:ax2148="http://mandate.result.service.soap.CDRator.com/xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ax2147:PlaceShopOrderResultDTO"> 
<ax2130:id xsi:nil="true" /><ax2140:description>SOAP_GLOBAL_SUCCESS</ax2140:description> 
<ax2147:subscriptions xsi:type="ax2127:SubscriptionDTO"><ax2130:id>201501070917439804</ax2130:id> 
<ax2130:id>201501070917439804</ax2130:id> 
</ns:return></ns:placeShopOrderResponse> 
</soapenv:Body> 
</soapenv:Envelope> 

: 여기 내 XML이다. 나는 XML에서 노드 값을 얻기 위해 이러한 쿼리를 실행하기 위해 새로운 아주 많이 나는 위의 질의

SELECT extractvalue(RESPONSE_XML, '/*/ax2130/*/id/@value') 
FROM SOAP_MONITORING where WEB_SERVICE_NAME='RatorWebShopService' and WEB_METHOD_NAME='placeShopOrder' 

을 시도했지만 오류

ORA-00932: inconsistent datatypes: expected - got - 
00932. 00000 - "inconsistent datatypes: expected %s got %s" 

을 받았다.

+1

빠른 대답은 'XMLType (RESPONSE_XML)'을 사용하기는하지만 이것은 유효한 XML로 보이지 않습니다 :'LPX-00225 : end-element tag "ns : return"은 start-element tag와 일치하지 않습니다 "ax2147 : . 끝 태그가없는 것처럼 보입니까? (또한 ['extractvalue()'는 더 이상 사용되지 않습니다.] (https://docs.oracle.com/cd/E11882_01/server.112/e41084/functions061.htm)). –

+0

실제로 그것의 거대한 XML과 나는 그것으로부터 약간의 부분을 삭제했다. 그래서 여기에 보여줄 수 있습니다. XMLType을 사용하여 쿼리를 알려주시겠습니까? 내 열 데이터 형식이 CLOB 인 것처럼 작동합니까? –

+0

당신이 봐야한다고 생각 [여기] (http://stackoverflow.com/questions/4884421/oracle-10g-extract-data-select-from-xml-clob-type) – Aramillo

답변

0

당신은 그냥와, 유효의 가정로 XMLType에 CLOB로 변환 할 수 있습니다 :

extractvalue(XMLType(RESPONSE_XML), ... 

회원님이 거기에 XML을 저장하는 경우 귀하의 열 유형이 XMLTYPE되지 않은,하지만 완전히없는 이유 확인 관련된.

SELECT extractvalue(XMLType(RESPONSE_XML), 
    '//ax2130:id/text()', 
    'xmlns:ax2130="http://core.data.soap.CDRator.com/xsd"') 
FROM SOAP_MONITORING 
where WEB_SERVICE_NAME='RatorWebShopService' and WEB_METHOD_NAME='placeShopOrder'; 

을 ...하지만 당신은 얻을 수 있도록 여러 ID가 :

그런 다음 extractvalue()에 네임 스페이스를 제공 할 수 ORA-19025: EXTRACTVALUE returns value of only one node을.

그리고 extractvalue되지 않습니다, as noted in the documentation

당신은 특별히 여기에, 대신위한 XMLTable을 XQuery를 사용할 수 있습니다.

SELECT xt.id 
FROM SOAP_MONITORING sm 
CROSS JOIN XMLTable(XMLNAMESPACES (
     'http://schemas.xmlsoap.org/soap/envelope/' AS "soapenv", 
     'http://service.soap.CDRator.com' as "ns", 
     'http://core.data.soap.CDRator.com/xsd' as "ax2130", 
     'http://webshop.result.service.soap.CDRator.com/xsd' as "ax2147" 
    ), 
    'for $i in /soapenv:Envelope/soapenv:Body/ns:placeShopOrderResponse/ns:return/ax2147:subscriptions 
     return $i/ax2130:id' 
    passing XMLType(sm.RESPONSE_XML) 
    columns "ID" number path '/') xt 
where WEB_SERVICE_NAME='RatorWebShopService' and WEB_METHOD_NAME='placeShopOrder'; 

        ID 
--------------------- 
    201501070917439804 
    201501070917439804 

2 rows selected 

아니면 빈 것을 포함하여, 언제 어디서나 ax:2130 노드를 원한다면, 당신은 사용할 수 있습니다 :

SELECT xt.id 
FROM SOAP_MONITORING sm 
CROSS JOIN XMLTable(XMLNAMESPACES (
     'http://core.data.soap.CDRator.com/xsd' as "ax2130" 
    ), 
    'for $i in //ax2130:id return $i' 
    passing XMLType(sm.RESPONSE_XML) 
    columns "ID" number path '/') xt 
where WEB_SERVICE_NAME='RatorWebShopService' and WEB_METHOD_NAME='placeShopOrder'; 

        ID 
--------------------- 

    201501070917439804 
    201501070917439804 

3 rows selected 

ax2147:subscription 안에 중첩 된 ax2130:id 값을 원하는 가정이 XQuery를 사용할 수 있습니다

XMLNamespaces 절에 XQuery에서 참조 할 네임 스페이스 만 지정해야합니다.

당신이 필요한 경우 선택한 ID를 기반으로 다른 테이블에 가입 할 수 있습니다 :

는 대신에
"SELECT extractvalue(XMLTYPE(RESPONSE_XML), '/*/ax2130/*/id/@value') 
    FROM SOAP_MONITORING where WEB_SERVICE_NAME='RatorWebShopService' and WEB_METHOD_NAME='placeShopOrder'" 

:

SELECT xt.id 
FROM SOAP_MONITORING sm 
CROSS JOIN XMLTable(XMLNAMESPACES (
    ...) xt 
JOIN someothertable sot on sot.id = xt.id 
where sm.WEB_SERVICE_NAME='RatorWebShopService' 
and sm.WEB_METHOD_NAME='placeShopOrder'; 
+0

고맙습니다. 오래 동안 시도한 후에 작동합니다. 작은 쿼리. 이제 모든 SUBSCRIPTION_ID가 있습니다. 이 SUBSCRIPTION_ID를 가져 와서 다른 테이블과 조인하고 싶습니다. 그래서이 경우에이 전체 SQL 쿼리에 대한 별칭을 만들고이 SUBSCRIPTION_ID를 사용하여 다른 테이블과 조인 할 수 있습니까? –

+0

다른 테이블에 조인을 추가하고 조인 조건으로'xt.id'를 사용할 수 있습니다. 더 명확하게 만들고 추가 조인을 더 잘 수행 할 수 있도록 ANSI 형식 크로스 조인 (표 사이의 쉼표 대신)으로 변경했습니다. –

+0

대단히 감사합니다. 그것은 지금 잘 작동합니다 :) –

-1

SELECT extractvalue(RESPONSE_XML, '/*/ax2130/*/id/@value') 
    FROM SOAP_MONITORING where WEB_SERVICE_NAME='RatorWebShopService' and WEB_METHOD_NAME='placeShopOrder'