我在 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] 删除。
我来说两句