2013-09-10 4 views
3

Я использую SQL Server 2008 R2. Моя проблема в том, что я хочу подсчитать количество обращений, которые я получаю от запроса XQuery, используя FLWOR. Для каждого удара, я хочу, порядковый номер, например: 0,1,2,3,4 ...FLWOR in Sql server количество результатов

Мой запрос:

select @xml.query('for $s at $count in /Root/Persons/Person 
return <Person ID="{$count}">{$s}</Person>') 

Единственная проблема здесь это не поддерживается в SQL Server и я получаю сообщение об ошибке:

Msg 9335, Level 16, State 1, Line 16 
XQuery [query()]: The XQuery syntax 'at' is not supported. 

Я также попытался с ключевым словом, пусть и определить новую переменную, но я не знаю, как увеличить значение этой переменной на каждой итерации?

Спасибо за ответы на все вопросы, Frenky

ответ

4

XQuery является декларативным языком, you cannot use let to increment a counter.

Довольно хак обходного путь к отсутствующим at функции будет считать предыдущем Sibling <person/> тегов:

for $person in /Root/Persons/Person 
let $count := count($person/preceding-sibling::Person) + 1 
return <Person ID="{$count}">{$person}</Person> 

Имейте в виде, что этот код будет иметь O(n^2) выполнение, если не оптимизируется исполнение двигателя (который будет вероятно, не делают) из-за повторных предшествующих сканов брака.


Редактировать: Как указано в комментариях, MS SQL не поддерживает даже preceding-sibling оси. Тем не менее, они поддерживают << node order comparison operator. Этот запрос должен быть полностью поддерживается:

for $person in /Root/Persons/Person 
let $count := count($person/parent::Persons/Person[. << $person]) + 1 
return <Person ID="{$count}">{$person}</Person> 

Кстати, вы, возможно, только нужно вставить имя человека, поэтому лучше использовать

(: snip :) 
return <Person ID="{$count}">{data($person)}</Person> 
+0

Большое спасибо за ответ. В Sql-сервере 2008R2 предыдущий-сиблинг также не поддерживается, полученная ошибка: Msg 9335, уровень 16, состояние 1, строка 16 XQuery [query()]: Синтаксис XQuery «previous-sibling» не поддерживается , – FrenkyB

+1

Ничего себе, не ожидал, что Microsoft сильно искалечила XQuery. Я расширил свой ответ еще одним уродливым обходным решением, которое должно быть поддержано. –

+0

Это работает)) Синтаксис такой же уродливый, какой он может быть и далек от интуитивного, но он работает)) Еще раз спасибо. – FrenkyB

0

Другой возможный состав, который может, возможно, будет легче читать, если вам не так хорошо знакомы с XQuery:

for $i in (1 to count(/Root/Persons/Person)) 
let $person := /Root/Persons/Person[$i] 
return 
    <Person ID="{$i}">{$person}</Person> 

Кроме того, если SQL Server делает/когда-либо поддержки (s) XQuery 3.0, то вы можете сделать следующее что довольно приятно:

/Root/Persons/Person ! <Person ID="{position()}">{data(.)}</Person> 
+0

Просто комплимент: на SQL Server 2005 у меня есть ошибка: Синтаксис XQuery 'to' не поддерживается. – Tito

Смежные вопросы