我有2个表,tr_testmodule
和TR_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
答案 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
)