i-o*_*one 13 xml t-sql sql-server
数据类型的nodes()方法是否按xml文档顺序返回节点?
例如,如果有以下数据:
declare @xml xml
set @xml = '<Fruits><Apple /><Banana /><Orange /><Pear /></Fruits>'
Run Code Online (Sandbox Code Playgroud)
被查询为
select T.c.query('.')
from @xml.nodes('/Fruits/*') T(c)
Run Code Online (Sandbox Code Playgroud)
元素将按文档顺序返回吗?select如果order by省略了子句,则返回的行的顺序是未定义的.是这样的select ... from ... .nodes(),还是特殊的?
在某些情况下,是否可以在以下查询的输出中获取非空行集:
declare @xml xml
set @xml = '<Data><Element OrderNo="1" /><Element OrderNo="2" />'
+ '<Element OrderNo="3" /><Element OrderNo="4" />'
+ '<Element OrderNo="5" /></Data>'
select * from (
select T.c.value('.', 'int') OrderNo1,
row_number() over (order by @@spid) OrderNo2
from @xml.nodes('/Data/Element/@OrderNo') T(c)) sq
where OrderNo1 != OrderNo2
Run Code Online (Sandbox Code Playgroud)
Mik*_*son 20
是,nodes()按文档顺序生成行集.在查询计划中使用的运算符是表值函数XML读取器.
表值函数XML Reader将XML BLOB作为参数输入,并生成以XML文档顺序表示XML节点的行集.其他输入参数可能会限制返回到XML文档子集的XML节点.
但是查询没有order by未定义的顺序,所以没有保证.
解决这个问题的一种方法是使用id由表值函数in row_number() over()子句生成的,并按顺序使用生成的数字.
select X.q
from
(
select T.c.query('.') as q,
row_number() over(order by T.c) as rn
from @xml.nodes('/Fruits/*') T(c)
) as X
order by X.rn
Run Code Online (Sandbox Code Playgroud)
这是不可能使用T.c一个在order by直接.尝试这会给你
消息493,级别16,状态1,行19
从nodes()方法返回的列'c'不能直接使用.它只能与四个XML数据类型的方法之一使用的,存在(),节点(),查询()和()的值,或在IS NULL和IS NOT NULL检查.
该错误没有提到它应该可以使用,row_number但它确实可以,并且很可能是可能得到修复的错误,因此上面的代码将失败.但直到SQL Server 2012它才能正常工作.
在不依赖于未记录的使用情况下获得保证订单的row_number方法是使用数字表,您可以按位置提取节点.
select T.c.query('.') as q
from Numbers as N
cross apply @xml.nodes('/Fruits/*[sql:column("N.Number")]') as T(c)
where N.Number between 1 and @xml.value('count(/Fruits/*)', 'int')
order by N.Number
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2498 次 |
| 最近记录: |