次の方法で共有


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 回使用して、 <Size> 要素と <Angle> 要素の値を比較します。

これは部分的な結果です。

<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 Construction (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. 製品モデルの特徴の説明の取得

次のクエリは、ProductModelIDProductModelName 属性、および最初の 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. カタログの説明に製品モデルの画像が含まれていない製品モデルを検索する

次のクエリでは、カタログの説明に <Picture> 要素が含まれていませんが、製品モデルの ProductModelID を取得します。

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)