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

Откуда:
Сообщений: 124
Добрый день!

Какие есть способы проапдейтить колонку с XML данными?
Data.modify('replace value of()...) работает очень медленно, а апдейтить надо XML с болшим количеством нод. Если что-то по быстрее?
16 июн 15, 15:06    [17777047]     Ответить | Цитировать Сообщить модератору
 Re: Update XML  [new]
WarAnt
Member

Откуда: Питер
Сообщений: 2421
Meriguan,

есть, переводите данные в реляционный вид, меняете, переводите обратно в xml
16 июн 15, 15:35    [17777227]     Ответить | Цитировать Сообщить модератору
 Re: Update XML  [new]
a_voronin
Member

Откуда: Москва
Сообщений: 4804
Meriguan
Добрый день!

Какие есть способы проапдейтить колонку с XML данными?
Data.modify('replace value of()...) работает очень медленно, а апдейтить надо XML с болшим количеством нод. Если что-то по быстрее?


Пишите на C#
16 июн 15, 16:12    [17777439]     Ответить | Цитировать Сообщить модератору
 Re: Update XML  [new]
Валдай
Member

Откуда:
Сообщений: 113
Meriguan
Добрый день!

Какие есть способы проапдейтить колонку с XML данными?
Data.modify('replace value of()...) работает очень медленно, а апдейтить надо XML с болшим количеством нод. Если что-то по быстрее?


можно попробовать построить xml индексы. тогда xpath под of(...) должен побыстрее выполнятся
17 июн 15, 13:52    [17782095]     Ответить | Цитировать Сообщить модератору
 Re: Update XML  [new]
Валдай
Member

Откуда:
Сообщений: 113
WarAnt
Meriguan,

есть, переводите данные в реляционный вид, меняете, переводите обратно в xml


Шутник :)
17 июн 15, 13:53    [17782101]     Ответить | Цитировать Сообщить модератору
 Re: Update XML  [new]
LexusR
Member

Откуда: Novosibirsk
Сообщений: 1873
Валдай
WarAnt
Meriguan,

есть, переводите данные в реляционный вид, меняете, переводите обратно в xml


Шутник :)


Какие шутки
if OBJECT_ID('RecoveryXML') is not null drop procedure RecoveryXML
GO
create procedure RecoveryXML(@id integer)
as
set nocount on
    declare 
    @localname nvarchar(4000),
    @node nvarchar(4000)

    select @localname=localname
    from #edgetable where id = @id
    -- пишем открывающийся тэг узла
    set @node = '<'+ @localname
    select @node = @node + case when t1.localname is null then '' else ' ' end+
           isnull(t1.localname,'')+
           case when t1.localname is not null then '="'+substring(t2.text,1,4000)+'"' else '' end
    from #edgetable t1
    left outer join #edgetable t2 on (t2.parentid = t1.id and t2.nodetype = 3)
    where t1.parentid=@id
    and t1.nodetype=2
    select @node = @node+'>'+ isnull(substring(text,1,4000),'')
    from #edgetable 
    where parentid=@id
    and nodetype=3
    insert into #XmlBuffer(Row)values(@node)
    -- пишем вложенные узлы
    declare Childs cursor local forward_only for
    select id from #edgetable
    where parentid=@id
    and nodetype=1
    open Childs
    fetch next from Childs into @id
    while @@fetch_status=0
        begin
          exec RecoveryXML @id 
          fetch next from Childs into @id
        end
        
    -- пишем закрывающийся тэг узла
    set @node = '</'+ @localname+'>'
    insert into #XmlBuffer(Row)values(@node)
GO
----------------------------------------------------------------------------------------------
DECLARE @idoc int
DECLARE @doc varchar(4000)
SET @doc ='<root>r
            <Level1>1                       
                <Level2 ID="12" Name="L12">2</Level2>
                <Level2 ID="13" Name="L13">3</Level2>
            </Level1>
            <Level1>1                       
                <Level2 ID="14" Name="L14">4</Level2>
            </Level1>
           </root>'

EXEC sp_xml_preparedocument @idoc OUTPUT, @doc

if OBJECT_ID('tempdb..#edgetable') is not null drop table #edgetable
select * into #edgetable from OPENXML (@idoc, '/',1) 
EXEC sp_xml_removedocument @idoc 

UPDATE e2 set e2.[text] = cast(cast(e2.[text] as varchar(max))+100 as varchar(max))
from #edgetable e1
left outer join #edgetable e2 on e2.parentid = e1.id
where e1.nodetype in (1,2) and e2.nodetype=3
and e1.localname = 'ID'


CREATE TABLE #XmlBuffer(Row nvarchar(4000))
exec RecoveryXML 0

set @doc = ''
select @doc=@doc + Row from #XmlBuffer
select cast(@doc as xml)


drop table #XmlBuffer
drop table #edgetable
drop procedure RecoveryXML
17 июн 15, 14:45    [17782454]     Ответить | Цитировать Сообщить модератору
 Re: Update XML  [new]
WarAnt
Member

Откуда: Питер
Сообщений: 2421
Валдай
WarAnt
Meriguan,

есть, переводите данные в реляционный вид, меняете, переводите обратно в xml


Шутник :)


а вы пробовали?
17 июн 15, 15:23    [17782830]     Ответить | Цитировать Сообщить модератору
 Re: Update XML  [new]
Валдай
Member

Откуда:
Сообщений: 113
LexusR
Валдай
пропущено...


Шутник :)


Какие шутки
if OBJECT_ID('RecoveryXML') is not null drop procedure RecoveryXML
GO
create procedure RecoveryXML(@id integer)
as
...
    while @@fetch_status=0
        begin
          exec RecoveryXML @id 
          fetch next from Childs into @id
        end
        
    -- пишем закрывающийся тэг узла
    set @node = '</'+ @localname+'>'
    insert into #XmlBuffer(Row)values(@node)


Лихо! Имеет право быть:)
Но.
1. Обработка построчно.
2. Сразу вложенность тэгов в лучшем случае 31. Лучше рекурсивный cte
темповую таблицу?
3. То что для типизированного xml (ну, например, частный случай схема) xpath-ом пишется в одну строку
  set @xml.modify('replace value of 
                   (//*:annotation/*:appinfo[@source="ncf"]/../..[fn:not(@maxOccurs="0")]/@maxOccurs)[1]
                   with ("0")')
. С распарсенными данными придёться написать вполне себе нормальный апдейт с рекурсией.

4. А как это быдет выглядеть, если идет не изменение, а вставка или удаление аттрибута(ов), элемента(ов)? Руками всталять строки, править parentid?
17 июн 15, 19:41    [17784227]     Ответить | Цитировать Сообщить модератору
 Re: Update XML  [new]
Валдай
Member

Откуда:
Сообщений: 113
WarAnt
Валдай
пропущено...


Шутник :)


а вы пробовали?


Имею "счастье" работать с системой, в которой разработчик пытается разложить по таблицам что-то типа этого:

http://repository.nsd.ru/versioned/accepted/examples/example/Repo/Repo_initial_registration_request_correction

а потом собрать обратно с изменениями. Как взгляну в процедуры так вздрогну.
17 июн 15, 19:51    [17784261]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить