xQuery - 多个节点
xQuery - multiple nodes
我有以下查询:
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]
?
为什么要投专栏XmlContent
?这应该是原生 XML 类型的列...这种转换非常昂贵,并且将 XML 保留在非 XML 列中是非常错误的...
不显示你的 XML 这是 蒙着眼睛飞 ,但我的魔法 crystal 球告诉我,你可能正在寻找类似的东西这个:
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
将 return 所有嵌套的 <ChangeInfo>
元素作为派生的 table.
WHERE
-子句使用XML方法.exist()
。这将检查给定 Xpath
在 XML 中任何位置的任何出现。如果需要,您可以从外部动态地用 sql:variable()
或 sql:column
引入文字 "John"。
一个提示:尝试了解 table 别名以及如何避免重复代码。
我有以下查询:
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]
?
为什么要投专栏XmlContent
?这应该是原生 XML 类型的列...这种转换非常昂贵,并且将 XML 保留在非 XML 列中是非常错误的...
不显示你的 XML 这是 蒙着眼睛飞 ,但我的魔法 crystal 球告诉我,你可能正在寻找类似的东西这个:
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
将 return 所有嵌套的 <ChangeInfo>
元素作为派生的 table.
WHERE
-子句使用XML方法.exist()
。这将检查给定 Xpath
在 XML 中任何位置的任何出现。如果需要,您可以从外部动态地用 sql:variable()
或 sql:column
引入文字 "John"。
一个提示:尝试了解 table 别名以及如何避免重复代码。