微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

sql-server – “nodes()”方法是否保留文档的顺序?

xml数据类型的nodes()方法是否以文件顺序返回节点?

例如,如果有如下数据:

declare @xml xml
set @xml = '<Fruits><Apple /><Banana /><Orange /><Pear /></Fruits>'

查询

select T.c.query('.')
from @xml.nodes('/Fruits/*') T(c)

将以文件顺序返回元素?如果order by被省略,则select已返回的行的顺序是未定义的.选择…从… .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

解决方法

是的,nodes()以文档顺序生成一个行集.查询计划中使用的运算符是 Table Valued Function XML Reader.

Table-valued Function XML Reader inputs an XML BLOB as a parameter and
produces a row set representing XML nodes in XML document order. Other
input parameters may restrict XML nodes returned to a subset of XML
document.

但是没有订单的查询一个未定义的顺序,所以没有保证.

解决这个问题的一种方法是使用row_number()over()子句中的表值函数生成的id,并按顺序使用生成的数字.

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命令是不可能的.尝试会给你

Msg 493,Level 16,State 1,Line 19

The column ‘c’ that was returned from the nodes() method cannot be used directly. It can only be used with one of the four XML data type methods,exist(),nodes(),query(),and value(),or in IS NULL and IS NOT NULL checks.

错误没有提到它应该与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

原文地址:https://www.jb51.cc/mssql/79158.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐