共用方式為


一般 XQuery 使用案例

適用於:SQL Server

本文提供 XQuery 使用的一般範例。

範例

A. 查詢目錄描述以尋找產品和權數

下列查詢會從產品目錄描述傳回產品型號標識碼和權數。 此查詢會建構具有下列格式的 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;

請注意上一個查詢中的下列考量:

  • namespace XQuery 序言中的關鍵字會定義查詢內文中使用的名稱空間字首。

  • 查詢主體會建構必要的 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"/>

下列查詢會擷取相同的資訊,但僅適用於其目錄描述包含規格中的<Specifications>重量、<Weight>元素、元素的產品型號。 此範例用 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;

在上一個查詢中,exist()子句中 WHERExml 資料類型的方法會檢查元素中<Specifications>是否有<Weight>元素。

B. 尋找類別目錄描述包括正面和小型圖片之產品型號的產品型號標識碼

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> 目錄描述的資料列。

  • 子句使用WHEREvalue()該方法兩次來比較 和<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 建構 (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() 傳回所有節點。 這包括項目節點、文字節點、處理指令和批注。

  • 這兩個 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 元素內<>分組的產品名稱、模型標識碼和功能

使用儲存在產品模型目錄描述中的資訊,下列查詢會列出元素內 <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. 擷取產品模型功能描述

下列查詢會建構 XML,其中包含 <Product> 具有 ProductModelID、 屬性 ProductModelName 和前兩個產品功能的元素。 具體來說,前兩個產品功能是元素的 <Features> 前兩個子元素。 如果有更多功能,則會傳回空白 <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 迴圈結構會擷取前兩個產品特性。 該 position() 函數用於查找序列中元素的位置。

F. 從產品目錄描述中尋找結尾為 ons

下列查詢會搜尋目錄說明,並傳回元素中 <ProductDescription> 名稱以 結 ons尾的所有元素。

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」 一詞的摘要描述

下列查詢會擷取產品模型,其類別目錄描述在摘要描述中包含 “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指定 query()xml 資料類型的 和 value() 方法。 因此,不是在兩個不同的查詢前例中重複命名空間宣告兩次,而是在查詢中使用前置詞 pd ,而且僅使用 WITH XMLNAMESPACES定義一次。

請注意上一個查詢中的下列考量:

  • WHERE 子句僅用於擷取目錄描述中元素中 <Summary> 包含「空氣動力學」一詞的列。

  • contains() 函數用於查看該單詞是否包含在文本中。

  • value() xml 資料類型的方法會將傳回的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) ,則會傳回產品型號識別碼。 否則,不會傳回。

  • 因為所有產品描述都包含一個 <Picture> 元素,所以在這種情況下結果集是空的。