如何根据另一个表的单行在一个表中插入多行?

时间:2015-05-28 07:19:39

标签: sql sql-server database

我有2个表,tr_testmoduleTR_Modulelocationdtl

select * from tr_testmodule -output like below (nmoduleno is primary key, vlocationno is varchar)

    nmoduleno   vlocationnno          
    1           3,65,6,9,63        
    2           13,625,62,91,613    

现在我想只使用单个查询为tr_testmodule的每一行插入tr_testmodule到TR_Modulelocationdtl的数据。

例如,我想为单个moduleno

插入多个行
select * from TR_Modulelocationdtl --(nid is pk,nlocationo-int)

        nid nmoduleno   nlocationno
        1   1             3 
        2   1             65
        3   1             6
        4   1             9
        5   1             63
        6   2             13
        7   2             625

我可以将这样的数据拆分成temptable(但仅限于单行)来临时表我可以将数据插入到我的'TR_Modulelocationdtl'

SELECT * INTO #TR_Modulelocationdtl FROM (SELECT data AS nLocationno FROM dbo.SplitString('1,23,2,3,5',',') ) AS nLocationno
select * from #TR_Modulelocationdtl 

nLocationno
1
23
2
3
5

3 个答案:

答案 0 :(得分:2)

试试这个:

DECLARE @t TABLE ( n INT, v VARCHAR(100) )
INSERT  INTO @t
VALUES  ( 1, '3,65,6,9,63' ),
        ( 2, '13,625,62,91,613' )


SELECT  n, s
FROM    @t
        CROSS APPLY ( SELECT    Split.a.value('.', 'VARCHAR(100)') AS s
                      FROM      ( SELECT    CAST ('<M>' + REPLACE(v, ',','</M><M>')
                                                  + '</M>' AS XML) AS s) AS A
                      CROSS APPLY s.nodes('/M') AS Split ( a )
                    ) ca   

输出:

n   s
1   3
1   65
1   6
1   9
1   63
2   13
2   625
2   62
2   91
2   613

答案 1 :(得分:0)

使用存储过程(或者是匿名块)很容易解决这个问题:循环遍历当前在tr_testmodule中的记录,拆分vlocationnno并循环遍历由此获得的位置,然后插入到tr_modulelocationdtl。

我不太了解SQL Server,所以这里有一个可以作为伪代码的等效Oracle脚本。我猜它应该很容易转换为SQL Server。

begin
  for rec in (select * from tr_testmodule) loop
    for loc in (select to_number(column_value) as nlocationno from xmltable(rec.vlocationnno)) loop
      insert into tr_modulelocationdtl (nmoduleno, nlocationno)
      values (rec.nmoduleno, loc.nlocationno);
    end loop;
  end loop;
  delete from tr_testmodule;
  commit;
end;

答案 2 :(得分:0)

insert into TR_Modulelocationdtl (nmoduleno,nlocationno,vlocationcode,dmodifyon)(

SELECT  nmoduleno, nlocal,PlaceMst.vCityCode,GETDATE()
FROM    tr_modulemst
        CROSS APPLY ( SELECT    Split.a.value('.', 'VARCHAR(100)') AS nlocal
                      FROM      ( SELECT    CAST ('<M>' + REPLACE(vlocationno, ',','</M><M>')
                                                  + '</M>' AS XML) AS vlocationno) AS A
                      CROSS APPLY vlocationno.nodes('/M') AS Split ( a )
                    ) ca 

                    left join PlaceMst
                    on PlaceMst.nCityNo = nlocal
                    )