2017-02-07 1 views
1

XML 필드 (SQL Server)의 경우 소스 테이블과 조건에 따라 모든 하위 노드에 노드를 추가해야합니다. 이 내 XML 데이터입니다 : 모든 <name>를 들어SQL 서버에서 XQuery를 사용하여 xml 하위 노드를 수정하는 방법

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>') 

, 나는 노드 <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)의 첫 번째 행에 대해서만. @T의 다른 2 개의 행은 무시됩니다. 모든 nodenumber을 추가해야합니다. 이것은 최종 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

while 루프를 사용합니다. 아래 코드를 확인하십시오. 도움이 될 수 있습니다.

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

관련 문제