使用SQL

时间:2018-06-21 16:50:41

标签: sql sql-server xml sql-server-2008

我的问题与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值,应使用该值插入节点。有帮助吗?!

(很抱歉有多余的机会)

2 个答案:

答案 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>