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