如何从 SQL CLOB 中提取 XML 键 "value"

How to pull XML key "value" from SQL CLOB

我正在尝试从存储在 CLOB 列中的 XML 中提取信息。我已经搜索了论坛,但到目前为止无法根据需要获取数据。我对 SQL 有基本的了解,但这超出了我的范围。

XML类似于以下内容:

<?xml version="1.0" encoding="UTF-8"?>

<Response>
    <Header>
        <OrderNum value="12354321"/>
        <ExtractDate value="11-30-2012"/>
        <RType value="Status"/>
        <Company value="Company"/>
    </Header>
    <Body>
        <Status>
            <Order>
                <ActivityType value="ValidateRequest"/>
                <EndUser>
                    <Name value="Schmo, Joe"/>
                    <Address>
                        <SANO value="12345"/>
                        <SASN value="Mickey Mouse"/>
                        <SATH value="Lane"/>
                        <SASS value="N"/>
                        <City value="Orlando"/>
                        <State value="FL"/>
                        <Zip value="34786"/>
                        <Number value="5550000"/>
                    </Address>
                </EndUser>
                <COS value="1"/>
                <TOS value="3"/>
                <MainNumber value="5550000"/>
            </Order>
            <ErrorCode value="400"/>
            <ErrorMessage value="RECEIVED"/>
        </Status>
    </Body>
</Response>

我想获取 "Address" 下的值。

我尝试了以下方法,但它 returns "NULL"。

SELECT EXTRACTVALUE(XMLTYPE(RESPONSE_CLOB),'/Response/Body/Status/Order/EndUser/Address/SANO') AS SANO
FROM RESPONSE_TABLE
WHERE ROWNUM < 2

我正在尝试获取它,这样我就可以在 "SANO" 中提取分配为 "value" 的“12345”(最终获取其他字段的值,但至少希望能够正常工作第一个)。

您当前正在检索节点的文本值,但 12345 是元素的值属性而不是其文本内容。所以你需要使用 @attribute 语法,即:

SELECT EXTRACTVALUE(XMLTYPE(RESPONSE_CLOB),'/Response/Body/Status/Order/EndUser/Address/SANO/@value') AS SANO
FROM RESPONSE_TABLE
WHERE ROWNUM < 2;

SANO                
--------------------
12345

但是extractvalue is deprecated; assuming you're on a recent version of Oracle it would be better to use an XMLQuery:

SELECT XMLQUERY(
  '/Response/Body/Status/Order/EndUser/Address/SANO/@value'
  PASSING XMLTYPE(RESPONSE_CLOB)
  RETURNING CONTENT
  ) AS SANO
FROM RESPONSE_TABLE
WHERE ROWNUM < 2;

您可能会发现使用 XMLTable 更容易 - 如果 XML 文档有多个 Address 节点,则这是必要的,但即使只有一个提取值,因为列也是减少重复,并且更容易检索合适的数据类型:

select x.*
from response_table rt
cross join xmltable(
  '/Response/Body/Status/Order/EndUser/Address'
  passing xmltype(rt.response_clob)
  columns sano number path 'SANO/@value',
    sasn varchar2(30) path 'SASN/@value',
    sath varchar2(10) path 'SATH/@value'
    -- etc.
) x
where rownum < 2;

                SANO SASN                           SATH      
-------------------- ------------------------------ ----------
               12345 Mickey Mouse                   Lane      

Read more 关于使用这些函数查询 XML 数据。