Share via


與階層有關的 XQuery

AdventureWorks 資料庫中的大部份 xml 類型資料行是半結構化文件。因此,儲存在每一個資料列中的文件看起來都不同。此主題的查詢範例說明如何從這些不同的文件中擷取資訊。

範例

A. 從製造指示文件中,擷取工作中心位置連以及這些位置上的第一個製造步驟

對於「產品型號 7」,此查詢建構的 XML 包含有 ProductModelIDProductModelName 屬性的 <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 初構中的 namespace 關鍵字定義命名空間前置詞。稍後在查詢主體中會使用此前置詞。

  • 內容切換 Token {) 和 (} 是用來將 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.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>

若只要擷取最上層電話號碼,尤其是 <AdditionalContactInfo> 的 <telephoneNumber> 子元素,則將查詢中的 FOR 運算式變更成

for $ph in /ci:AdditionalContactInfo/act:telephoneNumber.