2017-02-07 12 views
1

Для поля xml (SQL Server) мне нужно добавить узел в каждый поднод на основе исходной таблицы и условия. Это мой XML-данные:Как изменить поддомены xml с помощью XQuery на SQL Server

declare @X table (XMLDATA xml) 
insert @X values(' 
<row> 
    <node> 
    <name>Francesco</name> 
    </name> 
    <node> 
    <label>Alessandro</name> 
    </node> 
    <node> 
    <name>Daniele</name> 
    </node> 
</row>') 

Для каждого <name>, я хочу, чтобы добавить узел <number>. Спички для номеров и имен написаны в таблице @T:

declare @T table (name varchar(20), number int) 
insert @T values 
('Alessandro', 24) 
,('Francesco', 10) 
,('Daniele', 16) 

Чтобы обновить узлы, которые я использую XMLDATA.modify, и я использую условие XPATH, чтобы выбрать правильный узел:

update @X set XMLDATA.modify('insert element number {sql:column("number")} as last into (row/node[name=sql:column("name")])[1]') 
from @X 
cross join @T 

Запрос выше работ только для первой строки @T (в примере Alessandro/24). Остальные 2 строки @T игнорируются. Мне нужно добавить number на каждые node. Это последний XMLDATA:

<row> 
    <node> 
    <name>Francesco</name> 
    </node> 
    <node> 
    <name>Alessandro</name> 
    <number>24</number> 
    </node> 
    <node> 
    <name>Daniele</name> 
    </node> 
</row> 
+0

Даже если ответ Ronak Patel является хорошим способом обхода (который я проверил), я хотел бы знать, как работает 'fieldxml.modify()' и синтаксис для обновления многих узлов в строке. Я ошибаюсь, и обходной путь, который помог мне, должен быть отмечен как «правильный ответ»? – Radioleao

+0

Действительная точка ... Ниже моего ответа вы прокомментировали * Я просто пишу образец подмножества * (пожалуйста, добавьте ожидаемый выход, соответствующий образцу). Это поможет вам дать точный ответ. – Shnugo

+0

Я написал, что у меня сотни узлов на разных уровнях. Необходимо, чтобы я опубликовал реальный пример, чтобы спросить синтаксис MS SQL? – Radioleao

ответ

1

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

declare @X table (XMLDATA xml) 
insert @X values(' 
<row> 
    <node> 
    <name>Alessandro</name> 
    </node> 
    <node> 
    <name>Francesco</name> 
    </node> 
    <node> 
    <name>Daniele</name> 
    </node> 
</row>') 


declare @T table (name1 varchar(20), number int,RowID int identity(1,1) not null) 
insert @T values 
('Alessandro', 24) 
,('Francesco', 10) 
,('Daniele', 16) 

DECLARE @i int,@iCount int,@namevalue varchar(100)='',@number int 
SET @i = 1 


SELECT @iCount=MAX(RowID) FROM @T 

WHILE (@i <= @iCount) 
BEGIN 

SELECT @namevalue=name1 FROM @T WHERE [email protected] 
SELECT @number=number FROM @T WHERE [email protected] 

update @X set XMLDATA.modify('insert element number {sql:variable("@number")} as last into (row/node)[name=sql:variable("@namevalue")][1]') 
from @X 
cross join @T 

    SET @i = @i + 1 
END 

SELECT * FROM @X 

Выход:

<row> 
    <node> 
    <name>Alessandro</name> 
    <number>24</number> 
    </node> 
    <node> 
    <name>Francesco</name> 
    <number>10</number> 
    </node> 
    <node> 
    <name>Daniele</name> 
    <number>16</number> 
    </node> 
</row> 

Спасибо.

+0

Это хорошее решение, мне оно больше нравится, если вы используете курсор вместо цикла. Я хотел бы найти правильный запрос на обновление без использования какого-либо цикла, но это хороший способ обхода проблемы. Спасибо – Radioleao

+0

Это лучшее решение, которое я получил. Я ожидал, что какой-то другой синтаксис будет работать с субномами, но я боюсь, что нет ни одного – Radioleao

0

Если данные реальной жизни так же просто, как, например, решение можно найти гораздо проще:

declare @X table (XMLDATA xml) 
insert @X values(
'<row> 
    <node> 
    <name>Francesco</name> 
    </node> 
    <node> 
    <name>Alessandro</name> 
    </node> 
    <node> 
    <name>Daniele</name> 
    </node> 
</row>') 

declare @T table (name varchar(20), number int) 
insert @T values 
('Alessandro', 24) 
,('Francesco', 10) 
,('Daniele', 16); 

SELECT nm.value(N'.','nvarchar(max)') AS name 
     ,t.number 
FROM @X 
CROSS APPLY XMLDATA.nodes(N'/row/node/name') AS A(nm) 
INNER JOIN @T AS t ON t.name=nm.value(N'.','nvarchar(max)') 
FOR XML PATH('node'),ROOT('row') 

Если это не работает для вас, пожалуйста, предоставьте более реалистичные данные образцы!

+0

У меня есть сотни узлов и много подносов. Я просто пишу образец подмножества, чтобы быть как можно более ясным. – Radioleao