我有两张桌子.一个表A有n行数据,另一个表B是空的.我希望insertn行到表中B,表中的每一行有1行A.表B中将包含表中的几个字段A,包括表中的外键A.
最后,我希望每行中B有一行A.要做到这一点我用过:
INSERT INTO B(Col1
,Col2
,Col3
,Col4
,Col5
);
SELECT 100
,25
,'ABC'
,1
,A.ID
FROM Auctions A
Run Code Online (Sandbox Code Playgroud)
现在,我已将此代码放在存储过程中,此SP将int调用一个参数NumInserts.
我想插入n * NumInserts行.因此,如果n为10且NumInserts为5,我想运行此代码5*10(50)次.
换句话说,table A我希望每行中有insert5行table B.我该怎么办?
Cla*_*wer 15
create procedure insert_into_b
@numInserts int
as
begin
while @numInserts > 0
begin
insert into b (id)
select id from a
set @numInserts = @numInserts - 1
end
end
exec insert_into_b 2
Run Code Online (Sandbox Code Playgroud)
这是一个黑客,我不建议在生产或大量数据中使用它.但是,在开发快速和肮脏的场景中,我发现它通常很有用:
使用GO \[count\]执行批处理命令的指定次数.
具体来说,如果您调用了存储过程InsertAIntoB,则可以在Management Studio中运行它:
exec InsertAIntoB
GO 10
Run Code Online (Sandbox Code Playgroud)
(替换10为NumInserts)
我希望尽可能避免循环,这样我就不必在我的存储过程中维护一些容易破解且有些丑陋的循环结构.
您可以使用Numbers表,CROSS APPLY语句和现有INSERT语句轻松完成此操作.
鉴于您的数字表格如下所示:
Number
======
0
1
2
...
Run Code Online (Sandbox Code Playgroud)
您的SQL语句简单地变为:
INSERT INTO B
(
[Col1]
,[Col2]
,[Col3]
,[Col4]
,[Col5]
)
SELECT
100
,25
,'ABC'
,1
,a.ID
FROM
Auctions a
CROSS APPLY
Numbers n
WHERE
n.Number BETWEEN 1 AND @NumInserts
Run Code Online (Sandbox Code Playgroud)
如果使用得当,数字表可能很有用.如果你不熟悉它们,这里有一些资源和一些优点/缺点:
也许这个解决方案是过度的,如果@NumInserts总是一个相当小的数字,但如果你已经有一个数字表,你也可以利用它!
更新:
这是一个快速而简单的方法来填充从0到65,535的数字表:
CREATE TABLE Numbers
(
Number INT NOT NULL,
CONSTRAINT PK_Numbers
PRIMARY KEY CLUSTERED (Number)
WITH FILLFACTOR = 100
)
GO
INSERT INTO Numbers
SELECT
(a.Number * 256) + b.Number AS Number
FROM
(
SELECT number
FROM master..spt_values
WHERE
type = 'P'
AND number <= 255
) a (Number),
(
SELECT number
FROM master..spt_values
WHERE
type = 'P'
AND number <= 255
) b (Number)
GO
Run Code Online (Sandbox Code Playgroud)
图片来源: http ://dataeducation.com/you-require-a-numbers-table/