XQuery の一般的な使用例
適用対象:SQL Server
このトピックでは、XQuery の一般的な使用例について説明します。
例
A. 製品と重量を検索するためのカタログ説明のクエリ
次のクエリでは、製品カタログの説明に製品モデル ID と重量が含まれている場合、これらの情報を返します。 このクエリは、次の形式の XML を構築します。
<Product ProductModelID="...">
<Weight>...</Weight>
</Product>
クエリは次のとおりです。
SELECT CatalogDescription.query('
declare namespace p1="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";
<Product ProductModelID="{ (/p1:ProductDescription/@ProductModelID)[1] }">
{
/p1:ProductDescription/p1:Specifications/Weight
}
</Product>
') as Result
FROM Production.ProductModel
WHERE CatalogDescription is not null
上のクエリに関して、次の点に注意してください。
XQuery プロローグの namespace キーワードは、クエリ本文で使用される名前空間プレフィックスを定義します。
クエリ本文で、必要な XML が構築されます。
WHERE 句では、 exist() メソッドを使用して、製品カタログの説明を含む行のみを検索します。 つまり、 要素を含む <
ProductDescription
> XML です。
結果を次に示します。
<Product ProductModelID="19"/>
<Product ProductModelID="23"/>
<Product ProductModelID="25"/>
<Product ProductModelID="28"><Weight>Varies with size.</Weight></Product>
<Product ProductModelID="34"/>
<Product ProductModelID="35"/>
次のクエリでは、同じ情報を取得しますが、カタログの説明に重み、要素、 <Weight
> 仕様 <Specifications
> の 要素、 要素が含まれる製品モデルに対してのみ取得されます。 この例では、WITH XMLNAMESPACES を使用して、pd プレフィックスとその名前空間バインディングを宣言します。 このようにして、バインドは query() メソッドと exist() メソッドの両方で記述されません。
WITH XMLNAMESPACES ('https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription' AS pd)
SELECT CatalogDescription.query('
<Product ProductModelID="{ (/pd:ProductDescription/@ProductModelID)[1] }">
{
/pd:ProductDescription/pd:Specifications/Weight
}
</Product>
') as x
FROM Production.ProductModel
WHERE CatalogDescription.exist('/pd:ProductDescription/pd:Specifications//Weight ') = 1
前のクエリでは、WHERE 句の xml データ型の exist() メソッドは、 要素に<Specifications
>要素があるかどうかを<Weight
>確認します。
B. カタログの説明に正面からの小さな製品写真が含まれる製品モデルの製品モデル ID の検索
XML 製品カタログの説明には、製品の画像 、要素が <Picture
> 含まれます。 各写真には、いくつかのプロパティがあります。 これには、画像の角度、 <Angle
> 要素、および要素のサイズが <Size
> 含まれます。
カタログの説明に正面角図と小さい画像が含まれる製品モデルの場合、クエリは次の形式の XML を構築します。
< Product ProductModelID="...">
<Picture>
<Angle>front</Angle>
<Size>small</Size>
</Picture>
</Product>
WITH XMLNAMESPACES ('https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription' AS pd)
SELECT CatalogDescription.query('
<pd:Product ProductModelID="{ (/pd:ProductDescription/@ProductModelID)[1] }">
<Picture>
{ /pd:ProductDescription/pd:Picture/pd:Angle }
{ /pd:ProductDescription/pd:Picture/pd:Size }
</Picture>
</pd:Product>
') as Result
FROM Production.ProductModel
WHERE CatalogDescription.exist('/pd:ProductDescription/pd:Picture') = 1
AND CatalogDescription.value('(/pd:ProductDescription/pd:Picture/pd:Angle)[1]', 'varchar(20)') = 'front'
AND CatalogDescription.value('(/pd:ProductDescription/pd:Picture/pd:Size)[1]', 'varchar(20)') = 'small'
上のクエリに関して、次の点に注意してください。
WHERE 句では、 exist() メソッドを使用して、 要素を含む製品カタログの説明 <
Picture
> がある行のみを取得します。WHERE 句では、value() メソッドを 2 回使用して、 要素と><
Angle
要素の値を<Size
>比較します。
これは部分的な結果です。
<p1:Product
xmlns:p1="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription"
ProductModelID="19">
<Picture>
<p1:Angle>front</p1:Angle>
<p1:Size>small</p1:Size>
</Picture>
</p1:Product>
...
C. 製品モデル名と機能ペアのフラット リストを作成し、各ペアを <Features> 要素で囲みます。
製品モデル カタログの説明では、XML にはいくつかの製品機能が含まれています。 これらの機能はすべて 要素に <Features
> 含まれています。 このクエリでは、 XML コンストラクション (XQuery) を 使用して、必要な XML を構築します。 中かっこ内の式は、結果に置き換えられます。
SELECT CatalogDescription.query('
declare namespace p1="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";
for $pd in /p1:ProductDescription,
$f in $pd/p1:Features/*
return
<Feature>
<ProductModelName> { data($pd/@ProductModelName) } </ProductModelName>
{ $f }
</Feature>
') as x
FROM Production.ProductModel
WHERE ProductModelID=19
上のクエリに関して、次の点に注意してください。
$pd/p1:Features/* は の要素ノードの <
Features
>子のみを返しますが、$pd/p1:Features/node() はすべてのノードを返します。 返されるノードには、要素ノード、テキスト ノード、処理命令、コメントがあります。2 つの FOR ループでは、製品名と個々の特徴が返されるデカルト積が生成されます。
ProductName は属性です。 このクエリで構築された XML では、この属性を要素として返します。
これは部分的な結果です。
<Feature>
<ProductModelName>Mountain 100</ProductModelName>
<ProductModelID>19</ProductModelID>
<p1:Warranty
xmlns:p1="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelWarrAndMain">
<p1:WarrantyPeriod>3 year</p1:WarrantyPeriod>
<p1:Description>parts and labor</p1:Description>
</p1:Warranty>
</Feature>
<Feature>
<ProductModelName>Mountain 100</ProductModelName>
<ProductModelID>19</ProductModelID>
<p2:Maintenance xmlns:p2="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelWarrAndMain">
<p2:NoOfYears>10</p2:NoOfYears>
<p2:Description>maintenance contact available through your dealer
or any AdventureWorks retail store.</p2:Description>
</p2:Maintenance>
</Feature>
...
...
D. 製品モデルのカタログの説明から、Product> 要素内にグループ化された製品モデル名、モデル ID、および機能を<一覧表示します
次のクエリでは、製品モデルのカタログの説明に格納されている情報を使用して、Product> 要素内にグループ化された製品モデル名、モデル ID、および機能を<一覧表示します。
SELECT ProductModelID, CatalogDescription.query('
declare namespace pd="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";
<Product>
<ProductModelName>
{ data(/pd:ProductDescription/@ProductModelName) }
</ProductModelName>
<ProductModelID>
{ data(/pd:ProductDescription/@ProductModelID) }
</ProductModelID>
{ /pd:ProductDescription/pd:Features/* }
</Product>
') as x
FROM Production.ProductModel
WHERE ProductModelID=19
これは部分的な結果です。
<Product>
<ProductModelName>Mountain 100</ProductModelName>
<ProductModelID>19</ProductModelID>
<p1:Warranty>... </p1:Warranty>
<p2:Maintenance>... </p2:Maintenance>
<p3:wheel xmlns:p3="https://www.adventure-works.com/schemas/OtherFeatures">High performance wheels.</p3:wheel>
<p4:saddle xmlns:p4="https://www.adventure-works.com/schemas/OtherFeatures">
<p5:i xmlns:p5="http://www.w3.org/1999/xhtml">Anatomic design</p5:i> and made from durable leather for a full-day of riding in comfort.</p4:saddle>
<p6:pedal xmlns:p6="https://www.adventure-works.com/schemas/OtherFeatures">
<p7:b xmlns:p7="http://www.w3.org/1999/xhtml">Top-of-the-line</p7:b> clipless pedals with adjustable tension.</p6:pedal>
...
E. 製品モデルの特徴の説明の取得
次のクエリは、ProducModelID、ProductModelName 属性、および最初の 2 つの製品機能を持つ要素を含む <Product
> XML を構築します。 具体的には、最初の 2 つの製品機能は、 要素の最初の <Features
> 2 つの子要素です。 さらに機能がある場合は、空 <There-is-more/
> の要素を返します。
SELECT CatalogDescription.query('
declare namespace pd="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";
<Product>
{ /pd:ProductDescription/@ProductModelID }
{ /pd:ProductDescription/@ProductModelName }
{
for $f in /pd:ProductDescription/pd:Features/*[position()<=2]
return
$f
}
{
if (count(/pd:ProductDescription/pd:Features/*) > 2)
then <there-is-more/>
else ()
}
</Product>
') as Result
FROM Production.ProductModel
WHERE CatalogDescription is not NULL
上のクエリに関して、次の点に注意してください。
- FOR ...RETURN ループ構造は、最初の 2 つの製品機能を取得します。 position() 関数は、シーケンス内の要素の位置を検索するために使用されます。
F. 製品カタログの説明からの "ons" で終わる要素名の検索
次のクエリでは、カタログの説明を検索し、名前が "ons" で <ProductDescription
> 終わる要素内のすべての要素を返します。
SELECT ProductModelID, CatalogDescription.query('
declare namespace p1="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";
for $pd in /p1:ProductDescription/*[substring(local-name(.),string-length(local-name(.))-2,3)="ons"]
return
<Root>
{ $pd }
</Root>
') as Result
FROM Production.ProductModel
WHERE CatalogDescription is not NULL
これは部分的な結果です。
ProductModelID Result
-----------------------------------------
19 <Root>
<p1:Specifications xmlns:p1="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription">
...
</p1:Specifications>
</Root>
G. "空力" という単語を含む概要の説明を検索する
次のクエリでは、カタログの説明の概要説明に "Aerodynamic" という語を含む製品モデルを取得します。
WITH XMLNAMESPACES ('https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription' AS pd)
SELECT ProductModelID, CatalogDescription.query('
<Prod >
{ /pd:ProductDescription/@ProductModelID }
{ /pd:ProductDescription/pd:Summary }
</Prod>
') as Result
FROM Production.ProductModel
WHERE CatalogDescription.value('
contains( string( (/pd:ProductDescription/pd:Summary)[1] ),"Aerodynamic")','bit') = 1
SELECT クエリでは、xml データ型の query() メソッドと value() メソッドが指定されることに注意してください。 このため、2 つの異なるクエリ プロローグ内でそれぞれ名前空間の宣言を繰り返す手間を省き、クエリ内で使用されるプレフィックス pd を WITH XMLNAMESPACES を使用して一度だけ定義しています。
上のクエリに関して、次の点に注意してください。
WHERE 句は、カタログ記述に 要素に "空力" <
Summary
> という単語が含まれている行のみを取得するために使用されます。contains() 関数は、単語がテキストに含まれているかどうかを確認するために使用されます。
xml データ型の value() メソッドは、contains() によって返される値を 1 と比較します。
結果を次に示します。
ProductModelID Result
-------------- ------------------------------------------
28 <Prod ProductModelID="28">
<pd:Summary xmlns:pd="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription">
<p1:p xmlns:p1="http://www.w3.org/1999/xhtml">
A TRUE multi-sport bike that offers streamlined riding and a
revolutionary design. Aerodynamic design lets you ride with the
pros, and the gearing will conquer hilly roads.</p1:p>
</pd:Summary>
</Prod>
H. カタログの説明に製品モデルの画像が含まれていない製品モデルを検索する
次のクエリでは、カタログの説明に 要素が含まれない製品モデルの ProductModelID を <Picture
> 取得します。
SELECT ProductModelID
FROM Production.ProductModel
WHERE CatalogDescription is not NULL
AND CatalogDescription.exist('declare namespace p1="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";
/p1:ProductDescription/p1:Picture
') = 0
上のクエリに関して、次の点に注意してください。
WHERE 句の exist() メソッドが False (0) を返す場合は、製品モデル ID が返されます。 それ以外の場合は、返されません。
製品のすべての説明に 要素が <
Picture
> 含まれているため、この場合、結果セットは空です。
参照
階層に関係する XQuery
順序に関係する XQuery
リレーショナル データを処理する XQuery
XQuery での文字列検索
XQuery での名前空間の処理
WITH XMLNAMESPACES を使用したクエリへの名前空間の追加
XML データ (SQL Server)
XQuery 言語リファレンス (SQL Server)