Вы объявили ns2
, используя неверный путь, но вы все равно не обращаетесь к нему;поскольку orderIds
не имеет префикса пространства имен, вам нужно вместо этого объявить значение по умолчанию (или также):
XMLTable(XMLNAMESPACES (
default 'http://soap.com/xsd', 'http://soap.com' AS "ns2"
),
'for $i in //orderIDs return $i'
passing XMLType(sm.REQUEST_XML)
columns "ORDER_ID" VARCHAR2(500) path '/') xt_orderid
Здесь вам также не нужен for
, вы можете использовать более простойдорожка;демонстрация с вашими примерами данных в CTE:
with sm (request_xml) as (
select '<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns2:check xmlns:ns2="http://soap.com" xmlns="http://soap.com/xsd">
<ns2:request>
<orderIDs>201902281425597269</orderIDs>
</ns2:request>
</ns2:check>
</soap:Body>
</soap:Envelope>' from dual
)
select xt_orderid.order_id
from sm
cross join
XMLTable(XMLNAMESPACES (
default 'http://soap.com/xsd'
),
'//orderIDs'
passing XMLType(sm.REQUEST_XML)
columns "ORDER_ID" VARCHAR2(500) path '/') xt_orderid
/
ORDER_ID
--------------------------------------------------
201902281425597269
Вы также можете использовать подстановочный знак для пространства имен, но это не идеально, и, как правило, я бы предпочел указать полный путь (с соответствующим пространством имен для каждого узла), если онстатичный.И если у вашего XML будет только один идентификатор заказа, вы можете использовать XMLQuery вместо XMLTable, но я думаю, что вы действительно будете извлекать другую информацию из более крупного документа.