比較式 (XQuery)
適用対象:SQL Server
XQuery には、次の種類の比較演算子が用意されています。
一般的な比較演算子
値の比較演算子
ノード比較演算子
ノードの順序の比較演算子
一般的な比較演算子
一般的な比較演算子を使用して、アトミック値、シーケンス、またはその 2 つの組み合わせを比較できます。
一般的な演算子を次の表に定義します。
演算子 | 説明 |
---|---|
= | 等しい |
!= | 等しくない |
< | より小さい |
> | より大きい |
<= | 以下 |
>= | 以上 |
一般的な比較演算子を使用して 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 値の比較は正確には行えないので、不正確な結果になる場合があります。
いずれかの値が型指定されていない場合は、もう一方の値の型にキャストされます。 次の例では、値 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>
値の比較演算子
値の比較演算子は、アトミック値を比較するために使用されます。 クエリで値比較演算子ではなく、一般的な比較演算子を使用できることに注意してください。
値比較演算子は、次の表で定義されています。
演算子 | 説明 |
---|---|
eq | 等しい |
ne | 等しくない |
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 に常にキャストされます。
ノード比較演算子
ノード比較演算子 は、ノードの種類にのみ適用されます。 返される結果は、オペランドとして渡された 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>
ノードの順序の比較演算子
ノード順比較演算子は、ドキュメント内の位置に基づいてノードのペアを比較します。
ドキュメントの順序に基づいて行われる比較を次に示します。
<<
: オペランド 1 は、ドキュメントの順序で オペランド 2 の前にあります。>>
: オペランド 1 は、ドキュメントの順序で オペランド 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
上のクエリに関して、次の点に注意してください。
xmlデータ型の value() メソッドがクエリで使用されます。
クエリのブール値の結果は nvarchar(10) に変換され、返されます。
クエリは True を返します。