一般 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
請注意下列項目是從上一個查詢而來:
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. 尋找類別目錄描述包括正面和小型圖片之產品型號的產品型號標識碼
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() 方法兩次來比較 和
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() 會傳回所有節點。 這包括項目節點、文字節點、處理指令和批注。兩個 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 元素內<>分組的產品名稱、模型標識碼和功能。
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,其中包含具有 ProductModelID、ProductModelName 屬性和前兩個>Product
<產品功能的專案。 具體而言,前兩個產品功能是 元素的前兩個 <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」 結尾的產品目錄描述中尋找項目名稱
下列查詢會搜尋目錄描述,並傳回名稱以 「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」 一詞的摘要描述
下列查詢會擷取產品模型,其類別目錄描述在摘要描述中包含 “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() 方法。 因此,除了在兩個差異查詢初構中重複命名空間宣告兩次,而是在查詢中使用前置詞 pd,而且只會使用WITH XMLNAMESPACES來定義一次。
請注意下列項目是從上一個查詢而來:
WHERE 子句只會擷取目錄描述在 元素中包含 “Aerodynamic” 這個字的數據 <
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),則會傳回產品型號標識符。 否則不會傳回。
因為所有產品描述都包含元素 <
Picture
> ,所以在此情況下,結果集是空的。
另請參閱
涉及階層的 XQueries
涉及訂單的 XQueries
處理關係型數據的 XQueries
XQuery 中的字串搜尋
處理 XQuery 中的命名空間
使用 WITH XMLNAMESPACES 將命名空間加入至查詢
XML 資料 (SQL Server)
Xquery 語言參考 (SQL Server)