xQuery-多个节点

时间:2018-11-06 20:54:51

标签: sql xml tsql xpath xquery-sql

我有以下查询:

SELECT     
CAST(spi.dbo.UserInfo.XmlContent AS xml).value('(/UserInfo[1]/@SystemId)','VARCHAR(32)') as SystemId,
CAST(spi.dbo.UserInfo.XmlContent AS xml).value('(/UserInfo[1]/@LoginId)','VARCHAR(32)') as LoginId,
--CAST(spi.dbo.UserInfo.XmlContent AS xml).value('(/UserInfo[1]/ChangeInfo/@UserId)[3]','VARCHAR(32)')AS SystemID
CAST(spi.dbo.UserInfo.XmlContent AS xml).value('count(/UserInfo/ChangeInfo)', 'INT') AS 'Count'
FROM UserInfo
WHERE CAST(spi.dbo.UserInfo.XmlContent AS xml).value('(/UserInfo[1]/ChangeInfo)[1]','VARCHAR(32)') = 'John'

我遇到的问题是节点ChangeInfo在某些XML记录中可能是多个。

如何搜索所有节点,而不必明确地命名节点的数量,例如说ChangeInfo[1]

1 个答案:

答案 0 :(得分:0)

为什么需要强制转换列XmlContent?这应该是本机XML类型列。此转换非常昂贵,而将XML保留在非XML列中是非常错误的...

没有显示您的XML,这是被蒙住眼睛,但是我的魔幻水晶球告诉我,您可能正在寻找这样的东西:

SELECT     
    A.CastedToXml.value('(/UserInfo/@SystemId)[1]','VARCHAR(32)') as SystemId,
    A.CastedToXml.value('(/UserInfo/@LoginId)[1]','VARCHAR(32)') as LoginId,
    B.ci.value('(/UserInfo/ChangeInfo/@UserId)[1]','VARCHAR(32)') AS ChangeInfo_UserID,
    A.CastedToXml.value('count(/UserInfo/ChangeInfo)', 'INT') AS ChangeInfo_Count
FROM spi.dbo.UserInfo ui
OUTER APPLY(SELECT CAST(ui.XmlContent AS xml)) A(CastedToXml)
OUTER APPLY A.CastedToXml.nodes('/UserInfo/ChangeInfo') B(ci)
WHERE CastedToXml.exist('/UserInfo/ChangeInfo[text()="John"]')=1;

我使用APPLY xml-casted 列添加到结果集中。第二个APPLY将返回所有嵌套的<ChangeInfo>元素作为派生表。

WHERE子句使用XML方法.exist()。这将检查XML中任何位置给定Xpath的出现情况。如果需要,您可以从外部动态地用sql:variable()sql:column引入文字“ John”。

一个提示:尝试了解表别名以及如何避免重复代码。