Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Xml перебрать значения в цикле  [new]
Be_rude
Member

Откуда:
Сообщений: 1
Привет, каким образом нужно указывать порядковый номер нужного элемента в цикле?
Set @xml=‘
<Root>
<row>1</row>
<row>2</row>
<row>3</row>
</root/>’

Set @i=0
Set @value=@xml.value(/root/row/@value[1],varchar(10)) — так указываем первый элемент
While @value is not null
Begin
Set @i=@i+1

Set @value=@xml.value(/root/row/@value[как здесь указать переменную @i],varchar(10))
Loop
End


Сообщение было отредактировано: 18 окт 18, 00:13
18 окт 18, 00:06    [21707260]     Ответить | Цитировать Сообщить модератору
 Re: Xml перебрать значения в цикле  [new]
felix_ff
Member

Откуда: Moscow
Сообщений: 1698
Be_rude,

вы придумываете какой то свой синтаксис. может лучше огласите первичную задачу которую пытаетесь решить?
18 окт 18, 01:24    [21707291]     Ответить | Цитировать Сообщить модератору
 Re: Xml перебрать значения в цикле  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31783
felix_ff
Be_rude,

вы придумываете какой то свой синтаксис
Вот вот, ТС хотя бы работающий пример выложил (XML у него невалидный, получение первого элемента некорректное)

Если решать не задачу получения произвольного элемента XML в динамике по порядковому номеру, а задачу из заголовка "Xml перебрать значения в цикле", то её можно решать получением всех элементов в временную таблицу, и перебиранием их с помощью курсора
18 окт 18, 08:15    [21707354]     Ответить | Цитировать Сообщить модератору
 Re: Xml перебрать значения в цикле  [new]
Сон Веры Павловны
Member

Откуда:
Сообщений: 6123
alexeyvg
XML у него невалидный

не well-formed
18 окт 18, 09:30    [21707419]     Ответить | Цитировать Сообщить модератору
 Re: Xml перебрать значения в цикле  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31783
Сон Веры Павловны
alexeyvg
XML у него невалидный

не well-formed
Не знаю, что такое well-formed, но вот это: </root/> выглядит странно, как и незакрытая нода root
19 окт 18, 10:41    [21708611]     Ответить | Цитировать Сообщить модератору
 Re: Xml перебрать значения в цикле  [new]
Сон Веры Павловны
Member

Откуда:
Сообщений: 6123
alexeyvg
Не знаю, что такое well-formed, но вот это: </root/> выглядит странно, как и незакрытая нода root

Well-formed - просто правильно сформированный. Валидный - правильно сформированный и прошедший проверку правил (схема, DTD).
19 окт 18, 11:37    [21708786]     Ответить | Цитировать Сообщить модератору
Между сообщениями интервал более 1 года.
 Re: Xml перебрать значения в цикле  [new]
Борис Гаркун
Member

Откуда: Лермонтов
Сообщений: 250
alexeyvg

Если решать не задачу получения произвольного элемента XML в динамике по порядковому номеру, а задачу из заголовка "Xml перебрать значения в цикле", то её можно решать получением всех элементов в временную таблицу, и перебиранием их с помощью курсора

Здравствуйте! А можно пример?
12 янв 21, 16:45    [22262099]     Ответить | Цитировать Сообщить модератору
 Re: Xml перебрать значения в цикле  [new]
court
Member

Откуда:
Сообщений: 2250
Борис Гаркун
alexeyvg

Если решать не задачу получения произвольного элемента XML в динамике по порядковому номеру, а задачу из заголовка "Xml перебрать значения в цикле", то её можно решать получением всех элементов в временную таблицу, и перебиранием их с помощью курсора

Здравствуйте! А можно пример?
а зачем это нужно ?

а так-то, можно как-то так
declare @xml xml =
'<root>
<row>1</row>
<row>2</row>
<row>3</row>
</root>'


;with cte as (
	select 
		lvl	=1
		,val	=t.c.value('text()[1]', 'int') 
		,xml	=@xml 
	from @xml.nodes('/root/row[1]') as t(c)

	union all

	select
		cte.lvl + 1
		,t.c.value('text()[1]', 'int')
		,cte.xml
	from cte cross apply cte.xml.nodes('/root/row[sql:column("lvl")+1]') as t(c)
)
select lvl, val from cte

lvlval
11
22
33
12 янв 21, 17:43    [22262125]     Ответить | Цитировать Сообщить модератору
 Re: Xml перебрать значения в цикле  [new]
Борис Гаркун
Member

Откуда: Лермонтов
Сообщений: 250
court, спасибо. Мне нужно подсчитать сколько полей всего и сколько из них заполнено. Единственно у меня xml не такой однобокий как в примере ТС. Ключевой элемент называется item, а в нем куча вложенных полей с разными названиями, вот пример xml:
автор
<item>
<F_Partner_Types title="Тип потребителя" type="value">1</F_Partner_Types>
<C_Subscr_Code title="Лицевой счет" type="value">602060007031</C_Subscr_Code>
<N_Own_Subscr_Not_Fill title="Отказ от заполнения" type="value"/>
...
<N_Longitude title="Долгота" type="value">45.05138072</N_Longitude>
</item>

При этом поле оформленное как N_Own_Subscr_Not_Fill нужно считать незаполненным
12 янв 21, 17:51    [22262132]     Ответить | Цитировать Сообщить модератору
 Re: Xml перебрать значения в цикле  [new]
invm
Member

Откуда: Москва
Сообщений: 9644
Борис Гаркун
Мне нужно подсчитать сколько полей всего и сколько из них заполнено
declare @xml xml = '<item>
<F_Partner_Types title="Тип потребителя" type="value">1</F_Partner_Types>
<C_Subscr_Code title="Лицевой счет" type="value">602060007031</C_Subscr_Code>
<N_Own_Subscr_Not_Fill title="Отказ от заполнения" type="value"/>
<N_Longitude title="Долгота" type="value">45.05138072</N_Longitude>
</item>';

select
 count(*) as Всего, 
 sum(case when a.n.value('@title', 'varchar(30)') <> 'Отказ от заполнения' then 1 else 0 end) Заполнено
from
 @xml.nodes('/item/*') a(n);
12 янв 21, 18:08    [22262143]     Ответить | Цитировать Сообщить модератору
 Re: Xml перебрать значения в цикле  [new]
court
Member

Откуда:
Сообщений: 2250
invm
Борис Гаркун
Мне нужно подсчитать сколько полей всего и сколько из них заполнено
declare @xml xml = '<item>
<F_Partner_Types title="Тип потребителя" type="value">1</F_Partner_Types>
<C_Subscr_Code title="Лицевой счет" type="value">602060007031</C_Subscr_Code>
<N_Own_Subscr_Not_Fill title="Отказ от заполнения" type="value"/>
<N_Longitude title="Долгота" type="value">45.05138072</N_Longitude>
</item>';

select
 count(*) as Всего, 
 sum(case when a.n.value('@title', 'varchar(30)') <> 'Отказ от заполнения' then 1 else 0 end) Заполнено
from
 @xml.nodes('/item/*') a(n);
имхо, ТС под этим
Борис Гаркун
При этом поле оформленное как N_Own_Subscr_Not_Fill нужно считать незаполненным
имеет ввиду не конкретную ноду N_Own_Subscr_Not_Fill, а любую ноду с пустым text() (?)

select
 count(*) as Всего, 
 count(a.n.value('text()[1]','varchar(100)')) as Заполнено
from
 @xml.nodes('/item/*') a(n);
12 янв 21, 18:16    [22262149]     Ответить | Цитировать Сообщить модератору
 Re: Xml перебрать значения в цикле  [new]
court
Member

Откуда:
Сообщений: 2250
declare @xml xml =
'<item>
<F_Partner_Types title="Тип потребителя" type="value">1</F_Partner_Types>
<C_Subscr_Code title="Лицевой счет" type="value">602060007031</C_Subscr_Code>
<N_Own_Subscr_Not_Fill title="Отказ от заполнения" type="value"/>
<N_Longitude title="Долгота" type="value">45.05138072</N_Longitude>
</item>'

;with cte as (
	select 
		lvl	=1
		,name	=t.c.value('local-name(.)', 'varchar(100)') 
		,val	=t.c.value('text()[1]', 'varchar(100)') 
		,xml	=@xml 
	from @xml.nodes('/item/*[1]') as t(c)

	union all

	select
		cte.lvl + 1
		,t.c.value('local-name(.)', 'varchar(100)') 
		,t.c.value('text()[1]', 'varchar(100)')
		,cte.xml
	from cte cross apply cte.xml.nodes('/item/*[sql:column("lvl")+1]') as t(c)
)
select lvl, name, val from cte

lvlnameval
1F_Partner_Types1
2C_Subscr_Code602060007031
3N_Own_Subscr_Not_FillNULL
4N_Longitude45.05138072
12 янв 21, 18:22    [22262153]     Ответить | Цитировать Сообщить модератору
 Re: Xml перебрать значения в цикле  [new]
Борис Гаркун
Member

Откуда: Лермонтов
Сообщений: 250
court, спасибо! Да, это и нужно было. Вот это синтаксис... Просто китайская азбука пока для меня :) Буду изучать
13 янв 21, 09:45    [22262403]     Ответить | Цитировать Сообщить модератору
 Re: Xml перебрать значения в цикле  [new]
invm
Member

Откуда: Москва
Сообщений: 9644
court,

Можно гораздо проще
select
 row_number() over (order by a.n),
 a.n.value('local-name(.)', 'varchar(100)'),
 a.n.value('text()[1]', 'varchar(100)')
from
 @xml.nodes('/item/*') a(n);
13 янв 21, 10:04    [22262421]     Ответить | Цитировать Сообщить модератору
 Re: Xml перебрать значения в цикле  [new]
Борис Гаркун
Member

Откуда: Лермонтов
Сообщений: 250
invm, спасибо!
13 янв 21, 10:12    [22262433]     Ответить | Цитировать Сообщить модератору
 Re: Xml перебрать значения в цикле  [new]
court
Member

Откуда:
Сообщений: 2250
invm
court,

Можно гораздо проще
select
 row_number() over (order by a.n),
 a.n.value('local-name(.)', 'varchar(100)'),
 a.n.value('text()[1]', 'varchar(100)')
from
 @xml.nodes('/item/*') a(n);
да, так действительно проще. Спасибо !

Скажите, а вот это "поведение" row_number-а, конкретно order by a.n оно документировано ?
... я как-то не могу понять по чём оно, собственно, сортирует ))

select 
 a.n.query('.'),
 row_number() over (order by a.n),
 a.n.value('local-name(.)', 'varchar(100)'),
 a.n.value('text()[1]', 'varchar(100)')
from
 @xml.nodes('/item/*') a(n);

(No column name)(No column name)(No column name)(No column name)
<F_Partner_Types title="Тип потребителя" type="value">1</F_Partner_Types>1F_Partner_Types1
<C_Subscr_Code title="Лицевой счет" type="value">602060007031</C_Subscr_Code>2C_Subscr_Code602060007031
<N_Own_Subscr_Not_Fill title="Отказ от заполнения" type="value" />3N_Own_Subscr_Not_FillNULL
<N_Longitude title="Долгота" type="value">45.05138072</N_Longitude>4N_Longitude45.05138072
13 янв 21, 11:17    [22262500]     Ответить | Цитировать Сообщить модератору
 Re: Xml перебрать значения в цикле  [new]
invm
Member

Откуда: Москва
Сообщений: 9644
court
Скажите, а вот это "поведение" row_number-а, конкретно order by a.n оно документировано ?
Нет. По крайней мере, я не находил.
Но работает с 2005-го.
13 янв 21, 12:09    [22262540]     Ответить | Цитировать Сообщить модератору
 Re: Xml перебрать значения в цикле  [new]
court
Member

Откуда:
Сообщений: 2250
invm
court
Скажите, а вот это "поведение" row_number-а, конкретно order by a.n оно документировано ?
Нет. По крайней мере, я не находил.
Но работает с 2005-го.
Спасибо
13 янв 21, 13:16    [22262598]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить