Выражения последовательности (XQuery)

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

SQL Server поддерживает операторы XQuery, используемые для создания, фильтрации и объединения последовательности элементов. Элемент может быть атомарным значением или узлом.

Конструирование последовательностей

Оператор «запятая» позволяет сцеплять элементы в единую последовательность.

Последовательность может содержать повторяющиеся значения. Вложенные последовательности (последовательность в последовательности) всегда сворачиваются. Например, последовательность (1, 2, (3, 4, (5))) превращается в (1, 2, 3, 4, 5). Ниже приведены примеры конструирования последовательностей.

Пример A

Следующий запрос возвращает последовательность из пяти атомарных значений:

declare @x xml  
set @x=''  
select @x.query('(1,2,3,4,5)')  
go  
-- result 1 2 3 4 5  

Следующий запрос возвращает последовательность из двух узлов:

-- sequence of 2 nodes  
declare @x xml  
set @x=''  
select @x.query('(<a/>, <b/>)')  
go  
-- result  
<a />  
<b />  

Следующий запрос возвращает ошибку, так как конструируется последовательность из атомарных значений и узлов. Разнородные последовательности не поддерживаются.

declare @x xml  
set @x=''  
select @x.query('(1, 2, <a/>, <b/>)')  
go  

Пример Б

Следующий запрос конструирует последовательность из атомарных значений, соединяя последовательности разной длины в единую последовательность.

declare @x xml  
set @x=''  
select @x.query('(1,2),10,(),(4, 5, 6)')  
go  
-- result = 1 2 10 4 5 6  

Сортировку последовательности можно произвести по FLOWR и ORDER BY:

declare @x xml  
set @x=''  
select @x.query('for $i in ((1,2),10,(),(4, 5, 6))  
                  order by $i  
                  return $i')  
go  

Элементы в последовательности можно подсчитать с помощью функции fn:count( ).

declare @x xml  
set @x=''  
select @x.query('count( (1,2,3,(),4) )')  
go  
-- result = 4  

Пример В

Следующий запрос указан в столбце AdditionalContactInfo типа XML в таблице Contact. В этом столбце хранятся дополнительные контактные данные: адреса, номера телефонов и пейджеров. Номер <телефона>, <пейджер> и другие узлы могут отображаться в любом месте документа. Запрос создает последовательность, содержащую все дочерние <элементы телефона> узла контекста, а затем <дочерние элементы пейджера> . Обратите внимание на применение оператора последовательности в возвращаемом выражении ($a//act:telephoneNumber, $a//act:pager).

WITH XMLNAMESPACES ('https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes' AS act,  
 'https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactInfo' AS aci)  
  
SELECT AdditionalContactInfo.query('  
   for $a in /aci:AdditionalContactInfo   
   return ($a//act:telephoneNumber, $a//act:pager)  
') As Result  
FROM Person.Contact  
WHERE ContactID=3  

Результат:

<act:telephoneNumber xmlns:act="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes">  
  <act:number>333-333-3333</act:number>  
</act:telephoneNumber>  
<act:telephoneNumber xmlns:act="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes">  
  <act:number>333-333-3334</act:number>  
</act:telephoneNumber>  
<act:pager xmlns:act="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes">  
  <act:number>999-555-1244</act:number>  
  <act:SpecialInstructions>  
Page only in case of emergencies.  
</act:SpecialInstructions>  
</act:pager>  

Фильтрация последовательностей

Можно отфильтровать возвращаемую последовательность по выражению, добавив предикат. Дополнительные сведения см. в разделе "Выражения пути" (XQuery). Например, следующий запрос возвращает последовательность трех <a> узлов элементов:

declare @x xml  
set @x = '<root>  
<a attrA="1">111</a>  
<a></a>  
<a></a>  
</root>'  
SELECT @x.query('/root/a')  

Результат:

<a attrA="1">111</a>  
<a />  
<a />  

Чтобы получить только <a> элементы с атрибутом attrA, можно указать фильтр в предикате. Результирующая последовательность будет иметь только один <a> элемент.

declare @x xml  
set @x = '<root>  
<a attrA="1">111</a>  
<a></a>  
<a></a>  
</root>'  
SELECT @x.query('/root/a[@attrA]')  

Результат:

<a attrA="1">111</a>  

Дополнительные сведения о том, как указать предикаты в выражении пути, см. в разделе "Указание предикатов" на шаге выражения пути.

Следующий пример производит построение выражения последовательности из поддеревьев, а затем применяет к последовательности фильтр.

declare @x xml  
set @x = '  
<a>  
  <c>C under a</c>  
</a>  
<b>    
   <c>C under b</c>  
</b>  
<c>top level c</c>  
<d></d>  
'  

Выражение в (/a, /b) конструирует последовательность с поддеревьями /a и /b, и из результирующей последовательности отфильтровывается элемент <c>.

SELECT @x.query('  
  (/a, /b)/c  
')  

Результат:

<c>C under a</c>  
<c>C under b</c>  

Следующий пример показывает применение фильтра предиката. Выражение находит элементы <a> и>b< содержит элемент.<c>

declare @x xml  
set @x = '  
<a>  
  <c>C under a</c>  
</a>  
<b>    
   <c>C under b</c>  
</b>  
  
<c>top level c</c>  
<d></d>  
'  
SELECT @x.query('  
  (/a, /b)[c]  
')  

Результат:

<a>  
  <c>C under a</c>  
</a>  
<b>  
  <c>C under b</c>  
</b>  

Ограничения реализации

Существуют следующие ограничения:

  • Не поддерживается XQuery-выражение RANGE.

  • Последовательности должны быть однородными. В частности, все элементы последовательности должны быть узлами или атомарными значениями. Эта проверка выполняется статически.

  • Не поддерживается комбинирование последовательностей узлов операторами union, intersect и except.

См. также

Выражения XQuery