Запросы XQuery, использующие иерархию

Применимо к:SQL Server

Большинство столбцов типов XML в базе данных AdventureWorks — это полуструктурированные документы. Поэтому документы, хранящиеся в каждой строке, могут выглядеть по-разному. Примеры запросов в этом подразделе показывают, как извлечь данные из этих различных документов.

Примеры

О. Получение сведений о размещении цехов и о первом этапе производства в этих цехах из документов инструкций производства

Для модели продукта 7 запрос создает XML, включающий <>ManuInstrэлемент, с атрибутами 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 определяет префикс пространства имен. Затем данный префикс используется в теле запроса.

  • Токены переключения контекста, {) и (}, используются для переключения запроса из режима построения 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>  

Чтобы получить только номера телефонов верхнего уровня, в частности <telephoneNumber> дочерние элементы <AdditionalContactInfo>, выражение FOR в запросе изменяется на

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

См. также

Основы XQuery
Конструкторы XML (XQuery)
XML-данные (SQL Server)