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

Откуда:
Сообщений: 2
Добрый день!
Подскажите, как можно с минимальными затратами слить одноименные тэги в одно поле через разделитель? Облазил весь инет, нигде примеров не нашел :(

declare @doc int, @x xml = 
'<root>
 <data>
   <a>гы</a>
   <b>2</b>
   <b>33</b>
   <c>44</c>
 </data>
</root>';

exec sp_xml_preparedocument @doc output, @x;

select *
from openxml(@doc, '/root/data', 2)
with
(
 a char(2) 'a',
 b char(2) 'b', --здесь должно получиться "2;33;"
 c int 'c'
 )

exec sp_xml_removedocument @doc;


Кол-во тэга <b> заранее не известно. Можно ли что-то написать в XPath в ColPattern ?
Видел такую штуку, но можно ли и как её здесь прикрутить, не знаю: <xsl:value-of select="/root/item" separator=", "/>
25 сен 18, 18:08    [21685811]     Ответить | Цитировать Сообщить модератору
 Re: Слияние одноименных тэгов в OpenXML  [new]
Владимир Затуливетер
Member

Откуда:
Сообщений: 427
Можно вот так:
declare @xml xml = N'
<root>
  <data>
    <a>гы</a>
    <b>2</b>
    <b>33</b>
    <c>44</c>
  </data>
</root>
';

select x.c
     , a.val as a
     , b.val as b
     , c.val as c
from (select 1) x(c)
    outer apply ( 
        select concat(t.v.value('.', 'nvarchar(max)'), ';') 
        from @xml.nodes('root/data/a') t(v) 
        for xml path('') 
    ) a(val)
    outer apply ( 
        select concat(t.v.value('.', 'nvarchar(max)'), ';')
        from @xml.nodes('root/data/b') t(v) 
        for xml path('') 
    ) b(val)
    outer apply ( 
        select concat(t.v.value('.', 'nvarchar(max)'), ';')
        from @xml.nodes('root/data/c') t(v) 
        for xml path('') 
    ) c(val)
25 сен 18, 19:15    [21685878]     Ответить | Цитировать Сообщить модератору
 Re: Слияние одноименных тэгов в OpenXML  [new]
Сон Веры Павловны
Member

Откуда:
Сообщений: 5957
Nikls
Видел такую штуку, но можно ли и как её здесь прикрутить, не знаю: <xsl:value-of select="/root/item" separator=", "/>

Никак - эта штука является XSLT-инструкцией, а MSSQL из коробки XSLT не поддерживает.
Можно сделать так:
declare @doc int, @x xml;
set @x = 
'<root>
 <data>
   <a>гы</a>
   <b>2</b>
   <b>33</b>
   <c>44</c>
 </data>
 <data>
   <a>бу</a>
   <b>9</b>
   <b>888</b>
   <c>555</c>
 </data>
</root>';

exec sp_xml_preparedocument @doc output, @x;

select x.a, f.b, x.c, x.id
from openxml(@doc, '/root/data', 2)
with
(
  a char(2) 'a',
  c int 'c',
  id int '@mp:id'
) x
cross apply (
  select v.x.value('.', 'varchar(max)')
  from (
    select x2.b+';'
    from openxml(@doc, '/root/data/b', 2)
    with
    (
      b varchar(2) '.',
      parent int '@mp:parentId'
    ) x2
    where x2.parent=x.id
    for xml path(''), type
  ) v(x)
) f(b)
exec sp_xml_removedocument @doc;
26 сен 18, 06:17    [21686164]     Ответить | Цитировать Сообщить модератору
 Re: Слияние одноименных тэгов в OpenXML  [new]
Посетитель
Member

Откуда:
Сообщений: 1209
XQuery еще не предлагали?
select @x.query('for $b in /root/data/b return concat(data($b),'';'')')
26 сен 18, 08:49    [21686236]     Ответить | Цитировать Сообщить модератору
 Re: Слияние одноименных тэгов в OpenXML  [new]
Nikls
Member

Откуда:
Сообщений: 2
Всем спасибо!
Взял вариант Веры Павловны)
Вариант с concat ни в 2005ом ни в 2008 не работает, ругается, что нет такой функции
А последний вариант с x.query склеивает из всех блоков, а как его съэплаить по parentid ума не хватает, т.к. c query не работал.
26 сен 18, 10:12    [21686335]     Ответить | Цитировать Сообщить модератору
 Re: Слияние одноименных тэгов в OpenXML  [new]
Посетитель
Member

Откуда:
Сообщений: 1209
Nikls
Всем спасибо!
Взял вариант Веры Павловны)
Вариант с concat ни в 2005ом ни в 2008 не работает, ругается, что нет такой функции
А последний вариант с x.query склеивает из всех блоков, а как его съэплаить по parentid ума не хватает, т.к. c query не работал.


select b.b.query('for $b in b return concat(data($b),'';'')')
  from @x.nodes('/root/data') b(b)
26 сен 18, 10:19    [21686350]     Ответить | Цитировать Сообщить модератору
 Re: Слияние одноименных тэгов в OpenXML  [new]
invm
Member

Откуда: Москва
Сообщений: 9349
Если openxml не обязательно:
select
 t.n.value('a[1]', 'varchar(30)'),
 replace(t.n.query('data(b)').value('.', 'varchar(max)'), ' ', ';'),
 t.n.value('c[1]', 'int')
from
 @x.nodes('/root/data') t(n);
26 сен 18, 10:55    [21686403]     Ответить | Цитировать Сообщить модератору
 Re: Слияние одноименных тэгов в OpenXML  [new]
Посетитель
Member

Откуда:
Сообщений: 1209
invm
select
 t.n.value('a[1]', 'varchar(30)'),
 replace(t.n.query('data(b)').value('.', 'varchar(max)'), ' ', ';'),
 t.n.value('c[1]', 'int')
from
 @x.nodes('/root/data') t(n);


о как, даже проще оказывается можно. надо запомнить :)
26 сен 18, 11:11    [21686433]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить