为 Oracle Clob 提取节点值

Extract node value for Oracle Clob

我有一个 CLOB 列,其中包含 XML 样式的数据,尽管它看起来肯定没有父子节点关系;它看起来像这样:

<servicePointExternalId>8629391888</servicePointExternalId><externalSPType>E-M-COM</externalSPType><faType>M-STARTS</faType><requesterUserId>E05920</requesterUserId><replyToExternalSystem>D1YS</replyToExternalSystem><externalReferenceId>47676141503102</externalReferenceId><retryDetails><numberOfRetries>0</numberOfRetries><isToDoEntrySuppressed>false</isToDoEntrySuppressed><retryDateTime>2017-04-28-18.16.53</retryDateTime><currentErrorState>VALERROR</currentErrorState></retryDetails><contactDetails><customerName>Hofstader, Leonard</customerName><contactName>Hofstader, Leonard</contactName><accountId>5669202300</accountId><personId>9538791588</personId></contactDetails><saList><eventType>D1ST</eventType><saId>5668577181</saId></saList>

我试图从这个字段中提取 requesteruserID 值(应该是 E05920),但我收到了这个错误消息:

ORA-31011: XML parsing failed
ORA-19213: error occurred in XML processing at lines 1
LPX-00245: extra data after end of document
ORA-06512: at "SYS.XMLTYPE", line 272
ORA-06512: at line 1
31011. 00000 -  "XML parsing failed"
*Cause:    XML parser returned an error while trying to parse the document.
*Action:   Check if the document to be parsed is valid.

我做错了什么?

您的示例不是完整的 XML 文档 - 它没有父节点,只有相邻的子节点。

如果你想把它当作 XML 你需要把它包装在一个虚拟的根节点中,例如如果您的 CLOB 在名为 clob_col 的列中,您可以执行以下操作:

xmltype(to_clob('<root>') || clob_col || '</root>')

要获取您想要的特定节点值,您可以执行以下操作:

select xmlquery(
  '/root/requesterUserId/text()'
  passing xmltype(to_clob('<root>') || clob_col || '</root>')
  returning content) as result
from your_table;

RESULT                                                                          
--------------------------------------------------------------------------------
E05920

或者使用您作为评论添加的 table 和列名称:

select xmlquery(
  '/root/requesterUserId/text()'
  passing xmltype(to_clob('<root>') || A.BO_DATA_AREA || '</root>')
  returning content) as result
from CISADM.D1_ACTIVITY A

或者只是

select xmlquery(
  '/root/requesterUserId/text()'
  passing xmltype('<root>' || A.BO_DATA_AREA || '</root>')
  returning content) as result
from CISADM.D1_ACTIVITY A

您可以将 returns 的 XML 片段转换为另一种数据类型:

select cast(
  xmlquery( '/root/requesterUserId/text()'
    passing xmltype(to_clob('<root>') || A.BO_DATA_AREA|| '</root>')
    returning content)
  as varchar2(8)) as requesterUserId
from CISADM.D1_ACTIVITY A;

或者您可以使用 XMLTable instead of XMLQuery:

select x.requesterUserId
from CISADM.D1_ACTIVITY A
cross join xmltable(
  '/root'
  passing xmltype('<root>' || A.BO_DATA_AREA || '</root>')
  columns requesterUserId varchar2(8) path 'requesterUserId'
) x;

两者都给出一个纯字符串值:

REQUESTE
--------
E05920

Read more about XML processing.