序列表达式 (XQuery)
适用于:SQL Server
SQL Server支持用于构造、筛选和合并一系列项的 XQuery 运算符。 项可以是原子值,也可以是节点。
构造序列
可以使用逗号运算符来构造序列,将多个项连接成一个序列。
序列可以包含重复的值。 嵌套序列(序列内又有序列)将被折叠。 例如,序列 (1, 2, (3, 4, (5))) 变成 (1, 2, 3, 4, 5)。 下面是构造序列的示例。
示例 A
以下查询返回由五个原子值构成的序列:
declare @x xml
set @x=''
select @x.query('(1,2,3,4,5)')
go
-- result 1 2 3 4 5
以下查询返回由两个节点构成的序列:
-- sequence of 2 nodes
declare @x xml
set @x=''
select @x.query('(<a/>, <b/>)')
go
-- result
<a />
<b />
以下查询返回错误,因为您构造的序列同时包含原子值和节点。 这是一个异类序列,不支持此序列。
declare @x xml
set @x=''
select @x.query('(1, 2, <a/>, <b/>)')
go
示例 B
以下查询通过将四个不同长度的序列组合成一个序列,构造原子值序列。
declare @x xml
set @x=''
select @x.query('(1,2),10,(),(4, 5, 6)')
go
-- result = 1 2 10 4 5 6
可以使用 FLOWR 和 ORDER BY 对该序列进行排序:
declare @x xml
set @x=''
select @x.query('for $i in ((1,2),10,(),(4, 5, 6))
order by $i
return $i')
go
可以使用 fn:count () 函数对序列中的项进行计数。
declare @x xml
set @x=''
select @x.query('count( (1,2,3,(),4) )')
go
-- result = 4
示例 C
以下查询针对 Contact 表中 xml 类型的 AdditionalContactInfo 列指定。 此列存储附加联系信息,如一个或多个附加电话号码、寻呼机号码和地址。 telephoneNumber<>、<pager> 和其他节点可以出现在文档中的任意位置。 查询构造一个序列,该序列包含上下文节点的所有 <telephoneNumber> 子级,后跟 <寻呼器> 子级。 注意返回表达式 (($a//act:telephoneNumber, $a//act:pager)
) 中逗号序列运算符的使用。
WITH XMLNAMESPACES ('https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes' AS act,
'https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactInfo' AS aci)
SELECT AdditionalContactInfo.query('
for $a in /aci:AdditionalContactInfo
return ($a//act:telephoneNumber, $a//act:pager)
') As Result
FROM Person.Contact
WHERE ContactID=3
结果如下:
<act:telephoneNumber xmlns:act="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes">
<act:number>333-333-3333</act:number>
</act:telephoneNumber>
<act:telephoneNumber xmlns:act="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes">
<act:number>333-333-3334</act:number>
</act:telephoneNumber>
<act:pager xmlns:act="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes">
<act:number>999-555-1244</act:number>
<act:SpecialInstructions>
Page only in case of emergencies.
</act:SpecialInstructions>
</act:pager>
筛选序列
可以通过向表达式中添加谓词来筛选表达式返回的序列。 有关详细信息,请参阅 (XQuery) 的路径表达式 。 例如,以下查询返回三个元素节点的 <a
> 序列:
declare @x xml
set @x = '<root>
<a attrA="1">111</a>
<a></a>
<a></a>
</root>'
SELECT @x.query('/root/a')
结果如下:
<a attrA="1">111</a>
<a />
<a />
若要仅 <a
> 检索具有 attrA 属性的元素,可以在谓词中指定筛选器。 生成的序列将只有一个 <a
> 元素。
declare @x xml
set @x = '<root>
<a attrA="1">111</a>
<a></a>
<a></a>
</root>'
SELECT @x.query('/root/a[@attrA]')
结果如下:
<a attrA="1">111</a>
有关如何在路径表达式中指定谓词的详细信息,请参阅 在路径表达式步骤中指定谓词。
下面的示例生成子树的序列表达式并对该序列应用筛选器。
declare @x xml
set @x = '
<a>
<c>C under a</c>
</a>
<b>
<c>C under b</c>
</b>
<c>top level c</c>
<d></d>
'
(/a, /b)
中的表达式构造具有子树 /a
和 /b
的序列,并且该表达式将从得到的序列中筛选元素 <c>
。
SELECT @x.query('
(/a, /b)/c
')
结果如下:
<c>C under a</c>
<c>C under b</c>
下面的示例应用谓词筛选器。 表达式查找包含元素 <>a
的 元素和 。<c
><b
>
declare @x xml
set @x = '
<a>
<c>C under a</c>
</a>
<b>
<c>C under b</c>
</b>
<c>top level c</c>
<d></d>
'
SELECT @x.query('
(/a, /b)[c]
')
结果如下:
<a>
<c>C under a</c>
</a>
<b>
<c>C under b</c>
</b>
实现限制
限制如下:
不支持 XQuery 范围表达式。
必须是同类序列。 确切地说,序列中的所有项必须都是节点,或者都是原子值。 这是通过静态检查来确定的。
不支持使用 union、intersect 或 except 运算符组合节点序列。