Запросы 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)