适用范围: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;
请注意上一个查询中的以下注意事项:
namespaceXQuery prolog 中的关键字定义查询正文中使用的命名空间前缀。查询主体用于构造所需的 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 前缀及其命名空间绑定。 通过这种方式,该方法和exist()方法中query()均未描述绑定。
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. 为其目录说明包含前角和小幅图片的产品型号查找产品型号 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()该方法两次比较和<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< 元素内>分组的产品模型名称、模型 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. 检索产品型号功能说明
以下查询构造 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;
请注意上一个查询中的以下注意事项:
- ...
FORRETURN循环结构检索前两个产品功能。 该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指定 query()xml 数据类型的方法value()。 因此,前缀在两个差异查询 prolog 中重复两次,而不是重复命名空间声明,而是在查询中使用, pd 并且只使用 WITH XMLNAMESPACES一次。
请注意上一个查询中的以下注意事项:
该
WHERE子句仅用于检索目录说明包含元素中“Aerodynamic”一词的<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;
请注意上一个查询中的以下注意事项:
exist()如果子句中的WHERE方法返回 False (0),则返回产品模型 ID。 否则,不会返回它。由于所有产品说明都包含一个
<Picture>元素,因此在这种情况下,结果集为空。