基于XML Clob搜索字符串从oracle中提取行

基于XML Clob搜索字符串从oracle中提取行,xml,database,oracle,Xml,Database,Oracle,我们正在使用一种产品,该产品将审核信息存储在XML clob中的oracle数据库中。下面是xml格式 <Attributes> <Map> <entry key="messages"> <value> <List> <Message key="err_exception" type="Error"> <Parameters>

我们正在使用一种产品,该产品将审核信息存储在XML clob中的oracle数据库中。下面是xml格式

<Attributes>
  <Map>
    <entry key="messages">
      <value>
        <List>
          <Message key="err_exception" type="Error">
            <Parameters>
              <Message key="sailpoint.tools.GeneralException: The application script threw an exception: java.lang.Exception: This request could not be approved as you are the only available approval workgroup member; per CIS policy, a user is not allowed to approve their own request!! BSF info: script at line: 0 column: columnNo" type="Error"/>
            </Parameters>
          </Message>
        </List>
      </value>
    </entry>
  </Map>
</Attributes>

如果您有任何帮助,我们将不胜感激。

您的xml数据实际上与您提供给我们的xml格式不匹配。:)

XPath表达式中的一个级别是返回2个节点,而不是1个节点。我猜是
节点有多个子节点,但它可以是任何子节点。以下是解决该问题的方法:

-- sample data
with SPT_IDENTITY_REQUEST as (select to_clob('<Attributes>
  <Map>
    <entry key="messages">
      <value>
        <List>
          <Message key="err_exception" type="Error">
            <Parameters>
              <Message key="CIS policy sample exception #1" type="Error"/>
            </Parameters>
          </Message>
          <Message key="err_exception" type="Error">
            <Parameters>
              <Message key="CIS policy sample exception #2" type="Error"/>
            </Parameters>
          </Message>
        </List>
      </value>
    </entry>
  </Map>
</Attributes>') as attributes from dual)
-- your query
select * from (select *
from identityiq.SPT_IDENTITY_REQUEST att,
      xmltable('Attributes'
        passing xmltype(att.attributes)
        columns MessageXML XMLType path '/Attributes/Map/entry[@key="messages"]/value/List/Message[@key="err_exception"]' ) x,
      xmltable('/Message' -- add a second xmltable to handle multiple nodes at this level
        passing x.MessageXML
        columns Message varchar2(100) path '/Message/Parameters/Message/@key') m
      ) res
      where res.message is not null 
      and res.message like '%CIS policy%';
——示例数据

SPT_标识_请求为(选择关闭)(”,这将更深入地介绍它。

感谢@kfinity的快速响应。我同意我们可能会得到两个孩子。但是如果输出中有两个以上的孩子,该如何处理。如果是两个孩子,那么正如您提到的,我们可以在xmltable中处理。但是如果是两个以上的孩子,我们该如何处理?(2)我们可以像这样添加Xpath吗..像“%”这样的键以便我们只能选择所需的子项,请告诉我。上面的代码对于多条消息应该可以很好地工作-但是如果您在其他节点下有多个子项,例如消息中的多个参数,或者参数节点中有多条消息,那么您需要添加更多的xmltables。是的,有关如何使用Xpath匹配包含字符串的属性,请参见此问题。
ORA-19279: XPTY0004 - XQuery dynamic type mismatch: expected singleton sequence - got multi-item sequence
19279. 00000 -  "XPTY0004 - XQuery dynamic type mismatch: expected singleton sequence - got multi-item sequence" 
*Cause:    The XQuery sequence passed in had more than one item.
*Action:   Correct the XQuery expression to return a single item sequence.
-- sample data
with SPT_IDENTITY_REQUEST as (select to_clob('<Attributes>
  <Map>
    <entry key="messages">
      <value>
        <List>
          <Message key="err_exception" type="Error">
            <Parameters>
              <Message key="CIS policy sample exception #1" type="Error"/>
            </Parameters>
          </Message>
          <Message key="err_exception" type="Error">
            <Parameters>
              <Message key="CIS policy sample exception #2" type="Error"/>
            </Parameters>
          </Message>
        </List>
      </value>
    </entry>
  </Map>
</Attributes>') as attributes from dual)
-- your query
select * from (select *
from identityiq.SPT_IDENTITY_REQUEST att,
      xmltable('Attributes'
        passing xmltype(att.attributes)
        columns MessageXML XMLType path '/Attributes/Map/entry[@key="messages"]/value/List/Message[@key="err_exception"]' ) x,
      xmltable('/Message' -- add a second xmltable to handle multiple nodes at this level
        passing x.MessageXML
        columns Message varchar2(100) path '/Message/Parameters/Message/@key') m
      ) res
      where res.message is not null 
      and res.message like '%CIS policy%';