是的,nodes()
按文档顺序生成行集。查询计划中用于执行此操作的运算符是Table Valued Function XML Reader。
表值函数 XML Reader 输入一个 XML BLOB 作为参数,并生成一个行集,该行集表示 XML 文档顺序中的 XML 节点。其他输入参数可能会将返回的 XML 节点限制为 XML 文档的子集。
但是没有的查询order by
具有未定义的顺序,因此无法保证。
解决此问题的一种方法是id
在子句中使用表值函数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
不能直接T.c
在 an中使用order by
。尝试它会给你
Msg 493, Level 16, State 1, Line 19
从 nodes() 方法返回的列 'c' 不能直接使用。它只能用于四种 XML 数据类型方法之一,exist()、nodes()、query() 和 value(),或者用于 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