CREATE TABLE SportsEvent
(ID INT, Name NVARCHAR(20), Results XML);
GO
DECLARE @Results XML=
'<Athletics>
<Event ID="001" Name="100m">
<Gold>John Doe</Gold>
<Silver>Harry Smith</Silver>
<Bronze>Kenneth Brown</Bronze>
</Event>
<Event ID="002" Name="High Jump">
<Gold>Sarah Jones</Gold>
<Silver>Janice Johnson</Silver>
<Bronze>Alicia Armstrong</Bronze>
</Event>
</Athletics>'
INSERT INTO SportsEvent
VALUES(1, 'AthleticsDay', @Results);
SELECT * FROM SportsEvent;
如果我想根据事件ID提取元素,没问题:
SELECT Results.query('(/Athletics/Event[@ID="001"]/Gold)')
FROM SportsEvent
WHERE ID = 1
我可以使用相对引用做同样的事情:
SELECT Results.query('(Athletics/Event)[1]')
FROM SportsEvent
WHERE ID = 1
但是,如果我想根据相对或绝对来拉取事件名称?:
SELECT Results.query('(Athletics/Event[@Name])[@ID="001"]')
FROM SportsEvent
WHERE ID = 1
SELECT Results.query('(Athletics/Event[@Name])[1]')
FROM SportsEvent
WHERE ID = 1
...两者都会带回该事件的所有数据。
我尝试使用值方法:
SELECT Results.value('(/Athletics/Event/@Name)[1]','VARCHAR(20)')
FROM SportsEvent
WHERE ID = 1
...但这只适用于相对参考,即在这种情况下是XML中的第一组结果。
如果我想指定事件ID并仅返回事件名称(作为XML片段或数据/值),该怎么办?
答案 0 :(得分:2)
好吧,对某些人来说(很多人?)这看起来非常明显,但我会发布我的asnwer,以防止其他人花费一些令人沮丧的几个小时的时间绕圈子(就像我刚刚做的那样) ...
SELECT Results.value('(/Athletics/Event[@ID="001"]/@Name)[1]','VARCHAR(20)')
FROM SportsEvent
WHERE ID = 1
SELECT Results.value('(/Athletics/Event[@Name="100m"]/@ID)[1]','VARCHAR(20)')
FROM SportsEvent
WHERE ID = 1
SELECT Results.value('(/Athletics/Event[@Name="High Jump"]/@ID)[1]','VARCHAR(20)')
FROM SportsEvent
WHERE ID = 1
SELECT Results.value('(/Athletics/Event[@ID="002"]/@Name)[1]','VARCHAR(20)')
FROM SportsEvent
WHERE ID = 1
从我可以确定的是,您不能使用查询方法仅返回属性的值,查询必须使用不允许的元素之外的属性来编写。
然而,你可以使用如下的查询方法 - 路径末尾的'[1]'(单例)不是强制性的(它们与值方法一起使用)。你将得到的是包含指定属性的整个片段。
SELECT Results.query('(/Athletics/Event[@ID="002"][@Name])[1]')
FROM SportsEvent
WHERE ID = 1
SELECT Results.query('(/Athletics/Event[@Name="100m"][@Name])[1]')
FROM SportsEvent
WHERE ID = 1
希望这有助于某人。
欢迎任何评论,更正或补充。 感谢。