涉及层次结构的 XQuery
AdventureWorks2008R2 数据库中的大多数 xml 类型列是半结构化文档。因此,每行中存储的文档可能看起来不同。本主题中的查询示例说明如何从这些不同的文档提取信息。
示例
A. 从生产说明文档检索生产车间以及这些生产车间的第一个生产步骤
对于产品型号 7,查询构造了包括下列内容的 XML:具有 ProductModelID 和 ProductModelName 属性的 <ManuInstr> 元素,以及一个或多个 <Location> 子元素。
每个 <Location> 元素具有它自己的属性集和一个 <step> 子元素。此 <step> 子元素是生产车间的第一个生产步骤。
SELECT Instructions.query('
declare namespace AWMI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";
<ManuInstr ProdModelID = "{sql:column("Production.ProductModel.ProductModelID") }"
ProductModelName = "{ sql:column("Production.ProductModel.Name") }" >
{
for $wc in //AWMI:root/AWMI:Location
return
<Location>
{$wc/@* }
<step1> { string( ($wc//AWMI:step)[1] ) } </step1>
</Location>
}
</ManuInstr>
') as Result
FROM Production.ProductModel
WHERE ProductModelID=7;
请注意上述查询的以下方面:
XQuery Prolog 中的 namespace 关键字定义命名空间前缀。随后,将在查询正文中使用此前缀。
上下文切换标记 {) 和 (} 用于将查询从 XML 构造切换到查询计算。
sql:column() 用于在正构建的 XML 中包括关系值。
在构造 <Location> 元素时,$wc/@* 将检索所有生产车间属性。
string() 函数返回 <step> 元素的字符串值。
下面是部分结果:
<ManuInstr ProdModelID="7" ProductModelName="HL Touring Frame">
<Location LocationID="10" SetupHours="0.5"
MachineHours="3" LaborHours="2.5" LotSize="100">
<step1>Insert aluminum sheet MS-2341 into the T-85A
framing tool.</step1>
</Location>
<Location LocationID="20" SetupHours="0.15"
MachineHours="2" LaborHours="1.75" LotSize="1">
<step1>Assemble all frame components following
blueprint 1299.</step1>
</Location>
...
</ManuInstr>
B. 在 AdditionalContactInfo 列中查找所有电话号码
下面的查询通过在整个层次结构中搜索 <telephoneNumber> 元素来检索用于联系特定客户的附加电话号码。因为 <telephoneNumber> 元素可以出现在层次结构中任何位置,所以该查询在搜索中使用后代和自身运算符 (//)。
SELECT AdditionalContactInfo.query('
declare namespace ci="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactInfo";
declare namespace act="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes";
for $ph in /ci:AdditionalContactInfo//act:telephoneNumber
return
$ph/act:number
') as x
FROM Person.Person
WHERE BusinessEntityID = 291;
结果如下:
<act:number
xmlns:act="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes">
425-555-1112
</act:number>
<act:number
xmlns:act="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes">
425-555-1111
</act:number>
若要只检索顶级电话号码(即 <AdditionalContactInfo> 的 <telephoneNumber> 子元素),查询中的 FOR 表达式应变为
for $ph in /ci:AdditionalContactInfo/act:telephoneNumber.