我的问题与this问题有关。但是,我正在编写一个需要帮助的干净方案。我是SQL的初学者,如果我在任何地方都不正确,请原谅我。
我有一个过程(请继续。在此处复制一个小示例),它会散发出一堆XML。在第二步中,基于参数条件,我必须为每个CID在XML中插入一个节点,然后进行最终选择。我在下面添加了一个Rextester链接:
更新的链接: http://rextester.com/EFGQB11125
当前输出:
<Main>
<ID>1001</ID>
<details>
<name>John</name>
<age>12</age>
</details>
</Main>
<Main>
<ID>1002</ID>
<details>
<name>Rick</name>
<age>19</age>
</details>
</Main>
<Main>
<ID>1003</ID>
<details>
<name>Diane</name>
<age>25</age>
</details>
</Main>
<Main>
<ID>1004</ID>
<details>
<name>Kippy</name>
<age>26</age>
</details>
</Main>
所需的输出:
当@type ='N'/'U'时
<Main>
<ID>1001</ID>
<type>N</type>
<details>
<name>John</name>
<age>12</age>
</details>
</Main>
<Main>
<ID>1002</ID>
<type>U</type>
<details>
<name>Rick</name>
<age>19</age>
</details>
</Main>
<Main>
<ID>1003</ID>
<type>N</type>
<details>
<name>Diane</name>
<age>25</age>
</details>
</Main>
<Main>
<ID>1004</ID>
<type>N</type>
<details>
<name>Kippy</name>
<age>26</age>
</details>
</Main>
因此,对于每个CID,基于@type值,应使用该值插入节点。有帮助吗?!
(很抱歉有多余的机会)
答案 0 :(得分:1)
以下示例中使用的技巧使用了一些Dynamic Sql魔术。
基本上用每个ID的所有更新来构建1个大型SQL。
declare @Sql varchar(max);
select @Sql = concat(@Sql,'UPDATE #final SET xml_data.modify(''insert <type>',ctype,'</type> after (/Main/ID)[text()="',cid,'"][1]'');',CHAR(13),CHAR(10))
from #tbl;
-- select @Sql as xml_modify_sqls;
exec(@Sql);
select * from #final;
这是一些使用示例数据设置临时表的SQL:
IF OBJECT_ID('tempdb..#tbl') IS NOT NULL DROP TABLE #tbl;
create table #tbl (cid int, ctype varchar(5));
IF OBJECT_ID('tempdb..#cdetails') IS NOT NULL DROP TABLE #cdetails;
create table #cdetails (cid int, name varchar(5), age int);
IF OBJECT_ID('tempdb..#final') IS NOT NULL DROP TABLE #final;
create table #final (xml_data xml);
insert into #tbl (cid, ctype) values
(1001,'N'), (1002,'U'), (1003,'N'), (1004,'N');
insert into #cdetails (cid, name, age) values
(1001,'John',12), (1002,'Rick',19), (1003,'Diane',25), (1004,'Kippy',26);
insert into #final (xml_data)
select xml_data
from (
select
cd1.cid as ID,
-- type = t.ctype as type,
details =
(
select
cd.name,
cd.age
from #cdetails cd
where cd.cid = cd1.cid
For XML Path(''), Type
)
from #cdetails cd1
join #tbl t on cd1.cid = t.cid
For XML Path('Main')
) q(xml_data);
select * from #final;
答案 1 :(得分:1)
对于您而言,从XML中读取数据并从头开始重建它要容易得多:
;WITH cte AS
(
select m.value(N'(ID/text())[1]','int') AS ID
,m.value(N'(details/name)[1]','nvarchar(max)') AS DetailsName
,m.value(N'(details/age)[1]','int') AS DetailsAge
,t.ctype
from #final f
CROSS APPLY f.xml_data.nodes(N'/Main') A(m)
LEFT JOIN #tbl t ON t.cid=m.value(N'(ID/text())[1]','int') --left join, because I don't know if and ID is found as CID
)
SELECT ID
,ctype AS [type]
,DetailsName AS [details/name]
,DetailsAge AS [details/age]
FROM cte
FOR XML PATH('Main')
返回
<Main>
<ID>1001</ID>
<type>N</type>
<details>
<name>John</name>
<age>12</age>
</details>
</Main>
<Main>
<ID>1002</ID>
<type>U</type>
<details>
<name>Rick</name>
<age>19</age>
</details>
</Main>
<Main>
<ID>1003</ID>
<type>N</type>
<details>
<name>Diane</name>
<age>25</age>
</details>
</Main>
<Main>
<ID>1004</ID>
<type>N</type>
<details>
<name>Kippy</name>
<age>26</age>
</details>
</Main>