ExtractXML Oracle 查询返回 Null

高拉夫·卡布拉

我在 Oracle 12c 数据库上的表“数据”的“属性”列中有以下数据:

<Attributes>
  <Map>
    <entry key="accountFlags">
      <value>
        <List>
          <String>Normal User Account</String>
        </List>
      </value>
    </entry>
    <entry key="cn" value="paul.john"/>
    <entry key="department" value="IT"/>
    <entry key="description" value="New account. Automatically created"/>
    <entry key="displayName" value="John, Paul"/>
    <entry key="distinguishedName" value="CN=paul.john,OU=Users,DC=test,DC=com"/>
    <entry key="givenName" value="Paul"/>
    <entry key="homeMDB" value="CN=Test,CN=Databases,CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=test,DC=com"/>
    <entry key="l" value="London"/>
    <entry key="mail" value="[email protected]"/>
    <entry key="mailNickname" value="PaulJ"/>
    <entry key="manager" value="CN=brock.lesnar,OU=Users,DC=test,DC=com"/>
    <entry key="memberOf">
      <value>
        <List>
          <String>CN=Test1,OU=Rights,OU=Groups,DC=test,DC=com</String>
          <String>CN=Test2,OU=Rights,OU=Groups,DC=test,DC=com</String>
          <String>CN=Test3,OU=Rights,OU=Groups,DC=test,DC=com</String>
          <String>CN=Test4,OU=Rights,OU=Groups,DC=test,DC=com</String>
        </List>
      </value>
    </entry>
  </Map>
</Attributes>

我希望像这样从此列中提取“memberOf”的值:

MEMBER_OF
---------
CN=Test1,OU=Rights,OU=Groups,DC=test,DC=com
CN=Test2,OU=Rights,OU=Groups,DC=test,DC=com
CN=Test3,OU=Rights,OU=Groups,DC=test,DC=com
CN=Test4,OU=Rights,OU=Groups,DC=test,DC=com

我已经尝试使用以下返回 null 的查询:

SELECT EXTRACTVALUE(xmltype(attributes), '/Attributes/Map/entry[@key="memberOf"]/value/List/@String')
FROM DATA;

我也试过下面的查询,它也返回 null

SELECT EXTRACTVALUE(xmltype(attributes), '/Attributes/Map/entry[@key="memberOf"]/value[1]/List/@String')
FROM DATA;

不确定是否还有其他需要在查询中传递的内容?

亚历克斯·普尔

您的路径以 结尾.../@String,它正在寻找名为 的属性String,而不是节点。但是如果你解决了这个问题,你会得到:

ORA-19025: EXTRACTVALUE returns value of only one node

ExtractValue()反正早就弃用了您可以XMLQuery()改为使用,但这会为您提供单个 XML 片段而不是单独的字符串:

select xmlquery('/Attributes/Map/entry[@key="memberOf"]/value/List/String'
  passing xmltype(attributes)
  returning content) as member_of
from data;

MEMBER_OF                                                                       
--------------------------------------------------------------------------------
<String>CN=Test1,OU=Rights,OU=Groups,DC=test,DC=com</String><String>CN=Test2,OU=
Rights,OU=Groups,DC=test,DC=com</String><String>CN=Test3,OU=Rights,OU=Groups,DC=
test,DC=com</String><String>CN=Test4,OU=Rights,OU=Groups,DC=test,DC=com</String>

相反,XMLTable()像 Bikash 建议的那样,使用来获取单个值 - 但它可以更简单地完成,无需两个 XMLTable 调用:

select x.member_of
from data
cross join XMLTable('/Attributes/Map/entry[@key="memberOf"]/value/List/String'
  passing XMLType(attributes)
  columns member_of varchar2(60) path '.'
) x;

MEMBER_OF                                                   
------------------------------------------------------------
CN=Test1,OU=Rights,OU=Groups,DC=test,DC=com
CN=Test2,OU=Rights,OU=Groups,DC=test,DC=com
CN=Test3,OU=Rights,OU=Groups,DC=test,DC=com
CN=Test4,OU=Rights,OU=Groups,DC=test,DC=com

阅读更多


如果您想在同一个查询中获取其他数据,您可以将它们添加为更多columns子句,在树上引用备份 - 因为其余的都是单个节点,除非您有并需要显示多个帐户标志。

select x.*
from data
cross join XMLTable('/Attributes/Map/entry[@key="memberOf"]/value/List/String'
  passing XMLType(attributes)
  columns cn varchar2(20) path './../../../../entry[@key="cn"]/@value',
    department varchar2(10) path './../../../../entry[@key="department"]/@value',
    member_of varchar2(60) path '.'
) x;

CN                   DEPARTMENT MEMBER_OF                                                   
-------------------- ---------- ------------------------------------------------------------
paul.john            IT         CN=Test1,OU=Rights,OU=Groups,DC=test,DC=com                 
paul.john            IT         CN=Test2,OU=Rights,OU=Groups,DC=test,DC=com                 
paul.john            IT         CN=Test3,OU=Rights,OU=Groups,DC=test,DC=com                 
paul.john            IT         CN=Test4,OU=Rights,OU=Groups,DC=test,DC=com                 

虽然一旦你这样做了,如果你确实使用多个 XMLTable 调用,它可能更容易阅读和维护

select x1.cn, x1.department, x2.member_of
from data
cross join XMLTable('/Attributes/Map'
  passing XMLType(attributes)
  columns cn varchar2(20) path 'entry[@key="cn"]/@value',
    department varchar2(10) path 'entry[@key="department"]/@value',
    member_of_xml XMLType path 'entry[@key="memberOf"]'
) x1
cross join XMLTable('/entry/value/List/String'
  passing member_of_xml
  columns member_of varchar2(60) path '.'
) x2;

然后很容易添加第三个 XMLTable 调用来处理多个帐户标志。

您也可以在单个 XMLTable 中使用更复杂的 XPath 和循环等进行所有这些操作,但我认为这更清晰、更简单,除非您处理大型 XML 文档(以及很多文档),否则可能不会是显着的性能差异。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章