Share via


シーケンス式 (XQuery)

SQL Server では、アイテムのシーケンスの構築、フィルタ処理、および組み合わせに使用される、XQuery 演算子がサポートされます。アイテムはアトミック値またはノードのいずれかです。

シーケンスの構築

コンマ演算子を使用して、複数のアイテムを 1 つのシーケンスに連結するシーケンスを構築できます。

シーケンスには、重複する値を含めることができます。入れ子になったシーケンス、つまりシーケンス内にシーケンスがある場合、入れ子が解除され 1 つのシーケンスになります。たとえば、シーケンス (1, 2, (3, 4, (5))) は (1, 2, 3, 4, 5) になります。次に、シーケンス構築の例を示します。

例 A

次のクエリは 5 つのアトミック値のシーケンスを返します。

declare @x xml
set @x=''
select @x.query('(1,2,3,4,5)')
go
-- result 1 2 3 4 5

次のクエリは 2 つのノードのシーケンスを返します。

-- 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

次のクエリでは、異なる長さの 4 つのシーケンスを 1 つのシーケンスに組み合わせることにより、アトミック値のシーケンスが構築されます。

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 列に対して、次のクエリを指定します。この列には、1 つ以上の追加の電話番号、ポケットベル番号、住所などの追加の連絡先情報が格納されます。<telephoneNumber>、<pager>、およびその他のノードは、ドキュメントのどこにでも配置できます。クエリでは、コンテキスト ノードのすべての <telephoneNumber> の子と、その後に <pager> の子が含まれるシーケンスが構築されます。返される式 ($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)」を参照してください。たとえば次のクエリは、3 つの <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> 要素が 1 つだけ含まれます。

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 の各演算子を使用したノード シーケンスの組み合わせはサポートされません。

関連項目

概念