比較式 (XQuery)
適用対象: SQL Server
XQuery には、次の種類の比較演算子が用意されています。
一般的な比較演算子
値比較演算子
ノード比較演算子
ノード順序の比較演算子
一般的な比較演算子
一般的な比較演算子を使用して、アトミック値、シーケンス、またはその 2 つの組み合わせを比較できます。
一般的な演算子を次の表に定義します。
Operator | 説明 |
---|---|
= | 等しい |
!= | 等しくない |
< | より小さい |
> | より大きい |
<= | 以下 |
>= | 以上 |
一般的な比較演算子を使用して 2 つのシーケンスを比較し、2 番目のシーケンスに True を最初のシーケンスの値と比較する値が存在する場合、全体的な結果は True になります。 それ以外の場合は False です。 たとえば、(1, 2, 3) = (3, 4) は両方のシーケンスに値 3 があるので True になります。
declare @x xml
set @x=''
select @x.query('(1,2,3) = (3,4)')
比較する 2 つの値の型は、比較できる型である必要があります。 具体的には、値の型は静的に確認されます。 数値の比較の場合、数値型の上位変換が発生する場合があります。 たとえば、10 進数の値 10 を double 値 1e1 と比較すると、10 進値は double に変更されます。 double 値の比較は正確には行えないので、不正確な結果になる場合があります。
値の 1 つが型指定されていない場合は、もう一方の値の型にキャストされます。 次の例では、値 7 は整数として扱われます。 比較する前に、/a[1] の型指定されていない値が整数に変換されます。 整数比較は True を返します。
declare @x xml
set @x='<a>6</a>'
select @x.query('/a[1] < 7')
逆に、型指定されていない値が文字列または別の型指定されていない値と比較される場合は、xs:string にキャストされます。 次のクエリでは、文字列 6 が文字列 "17" と比較されます。 このクエリは文字列の比較になるので、False が返されます。
declare @x xml
set @x='<a>6</a>'
select @x.query('/a[1] < "17"')
次のクエリでは、AdventureWorks サンプル データベースに用意されている製品カタログから、製品モデルの小さいサイズの画像が返されます。 このクエリは、 PD:ProductDescription/PD:Picture/PD:Size
によって返されるアトミック値のシーケンスを、シングルトン シーケンス "small" と比較します。 比較が True の場合は、 <Picture> 要素を返します。
WITH XMLNAMESPACES ('https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription' AS PD)
SELECT CatalogDescription.query('
for $P in /PD:ProductDescription/PD:Picture[PD:Size = "small"]
return $P') as Result
FROM Production.ProductModel
WHERE ProductModelID=19
次のクエリでは、 <number> 要素の一連の電話番号を文字列リテラル "112-111-1111" と比較します。 このクエリでは、AdditionalContactInfo 列の電話番号要素のシーケンスを比較して、特定の顧客の特定の電話番号がドキュメントに存在するかどうかを判断します。
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.value('
/aci:AdditionalContactInfo//act:telephoneNumber/act:number = "112-111-1111"', 'nvarchar(10)') as Result
FROM Person.Contact
WHERE ContactID=1
クエリは True を返します。 これは、その数字がドキュメント内に存在することを示します。 次のクエリは、以前のクエリの少し変更されたバージョンです。 このクエリでは、ドキュメントから取得された電話番号の値が、2 つの電話番号値のシーケンスと比較されます。 比較が True の場合、 <number> 要素が返されます。
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('
if (/aci:AdditionalContactInfo//act:telephoneNumber/act:number = ("222-222-2222","112-111-1111"))
then
/aci:AdditionalContactInfo//act:telephoneNumber/act:number
else
()') as Result
FROM Person.Contact
WHERE ContactID=1
結果を次に示します。
\<act:number
xmlns:act="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes">
111-111-1111
\</act:number>
\<act:number
xmlns:act="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes">
112-111-1111
\</act:number>
値比較演算子
値の比較演算子は、アトミック値を比較するために使用されます。 クエリでは、値比較演算子の代わりに一般的な比較演算子を使用できます。
値比較演算子は、次の表で定義されています。
Operator | 説明 |
---|---|
eq | 等しい |
ne | Not equal |
lt | 指定の値より小さい |
gt | より大きい |
le | 以下 |
ge | 指定の値以上 |
2 つの値が選択した演算子に従って同じ値を比較すると、式は True を返します。 それ以外の場合は False を返します。 いずれかの値が空のシーケンスの場合、式の結果は False になります。
これらの演算子は、単一のアトミック値でのみ機能します。 つまり、オペランドの 1 つにシーケンスを指定することはできません。
たとえば、次のクエリでは、画像のサイズが "小さい" 製品モデルの <Picture> 要素を取得します。
SELECT CatalogDescription.query('
declare namespace PD="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";
for $P in /PD:ProductDescription/PD:Picture[PD:Size eq "small"]
return
$P
') as Result
FROM Production.ProductModel
WHERE ProductModelID=19
上のクエリに関して、次の点に注意してください。
declare namespace
は、後でクエリで使用される名前空間プレフィックスを定義します。<Size>要素の値は、指定されたアトミック値 "small" と比較されます。
値演算子はアトミック値でのみ機能するため、 data() 関数はノード値を取得するために暗黙的に使用されることに注意してください。 つまり、
data($P/PD:Size) eq "small"
も同じ結果になります。
結果を次に示します。
\<PD:Picture
xmlns:PD="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription">
\<PD:Angle>front\</PD:Angle>
\<PD:Size>small\</PD:Size>
\<PD:ProductPhotoID>31\</PD:ProductPhotoID>
\</PD:Picture>
値の比較でのデータ型の上位変換の規則は、一般的な比較でのデータ型の上位変換の規則と同じです。 また、SQL Server では、値の比較時に型指定されていない値に対して、一般的な比較で使用されるのと同じキャスト規則が使用されます。 それに対して、XQuery 仕様の規則では、値の比較時に型指定されていない値は xs:string に常にキャストされます。
ノード比較演算子
ノード比較演算子 ( is は、ノードの種類にのみ適用されます。 返される結果は、オペランドとして渡された 2 つのノードがソース ドキュメント内の同じノードを表しているかどうかを示します。 2 つのオペランドが同じノードの場合、この演算子は True を返します。 それ以外の場合、False を返します。
次のクエリでは、ワーク センターの場所 10 が特定の製品モデルの製造プロセスの最初の場所であるかどうかを確認します。
WITH XMLNAMESPACES ('https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions' AS AWMI)
SELECT ProductModelID, Instructions.query('
if ( (//AWMI:root/AWMI:Location[@LocationID=10])[1]
is
(//AWMI:root/AWMI:Location[1])[1] )
then
<Result>equal</Result>
else
<Result>Not-equal</Result>
') as Result
FROM Production.ProductModel
WHERE ProductModelID=7
結果を次に示します。
ProductModelID Result
-------------- --------------------------
7 <Result>equal</Result>
ノード順序の比較演算子
ノード順序比較演算子は、ドキュメント内の位置に基づいてノードのペアを比較します。
ドキュメントの順序に基づいて行われる比較を次に示します。
<<
: operand 1 がドキュメントの順序で operand 2 の前にあります。>>
: operand 1 ドキュメントの順序で operand 2 に従います。
次のクエリは、製品カタログの説明に、特定の製品のドキュメント注文の <Maintenance> 要素の前に表示される <Warranty> 要素がある場合に True を返します。
WITH XMLNAMESPACES (
'https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription' AS PD,
'https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelWarrAndMain' AS WM)
SELECT CatalogDescription.value('
(/PD:ProductDescription/PD:Features/WM:Warranty)[1] <<
(/PD:ProductDescription/PD:Features/WM:Maintenance)[1]', 'nvarchar(10)') as Result
FROM Production.ProductModel
where ProductModelID=19
上のクエリに関して、次の点に注意してください。
クエリでは、xmldata 型の value() メソッドが使用されます。
クエリのブール値の結果は、 nvarchar(10) に変換され、返されます。
クエリは True を返します。