涉及层次结构的 XQuery
适用于:SQL Server
AdventureWorks 数据库中的大多数 xml 类型列都是半结构化文档。 因此,每行中存储的文档可能看起来不同。 本主题中的查询示例说明如何从这些不同的文档提取信息。
示例
A. 从生产说明文档检索生产车间以及这些生产车间的第一个生产步骤
对于产品模型 7,查询构造包含 <ManuInstr
> 元素的 XML,其中包含 ProductModelID 和 ProductModelName 属性,以及一个或多个 <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
>由于 元素可以出现在层次结构中的任意位置,因此查询在搜索中使用子代和 self 运算符 (//) 。
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.Contact
WHERE ContactID = 1
结果如下:
\<act:number
xmlns:act="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes">
111-111-1111
\</act:number>
\<act:number
xmlns:act="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes">
112-111-1111
\</act:number>
若要仅检索顶级电话号码,特别是 <telephoneNumber
> 的 <AdditionalContactInfo
>子元素,查询中的 FOR 表达式将更改为
for $ph in /ci:AdditionalContactInfo/act:telephoneNumber
.