Share via


順序運算式(XQuery)

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> 子系,接著是 <pager> 子系。請注意,在 return 運算式 (($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 />

若只要擷取具有 attrA 屬性的 <a> 元素,您可以在述詞中指定篩選。產生的序列將只會有一個 <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>

下列範例會套用述詞篩選。運算式將尋找包含 <c> 元素的 <a> 元素和 <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 運算子結合的節點順序。

請參閱

概念