如何编写带循环的SQL Server存储过程,按GetDup列值插入重复行?
基于循环实现按
GetDup值插入重复记录的存储过程 没问题,我帮你写一个完全符合要求的存储过程,全程用循环语句实现。先明确核心需求:每条记录要根据GetDup的值复制对应次数——比如GetDup=1就复制1次,加上原记录一共2条;GetDup=2复制2次,加上原记录一共3条。
假设你的源表名为Customers,我们可以用游标配合WHILE循环的方式来实现,这是完全贴合你要求的循环语句方案:
CREATE PROCEDURE InsertDuplicateRecords AS BEGIN SET NOCOUNT ON; -- 声明变量存储游标读取的单条记录数据 DECLARE @GetDup INT, @CustomerName NVARCHAR(100), @CustomerAdd NVARCHAR(200); DECLARE @LoopCounter INT; -- 声明游标,遍历源表的所有记录 DECLARE CustomerCursor CURSOR FOR SELECT GetDup, CustomerName, CustomerAdd FROM Customers; -- 打开游标准备读取数据 OPEN CustomerCursor; -- 读取第一条记录到变量中 FETCH NEXT FROM CustomerCursor INTO @GetDup, @CustomerName, @CustomerAdd; -- 循环处理游标中的每一条记录 WHILE @@FETCH_STATUS = 0 BEGIN -- 初始化内部循环计数器,从1开始到GetDup的值 SET @LoopCounter = 1; -- 根据GetDup的值,循环插入对应次数的重复记录 WHILE @LoopCounter <= @GetDup BEGIN INSERT INTO Customers (GetDup, CustomerName, CustomerAdd) VALUES (@GetDup, @CustomerName, @CustomerAdd); SET @LoopCounter = @LoopCounter + 1; END -- 读取游标中的下一条记录 FETCH NEXT FROM CustomerCursor INTO @GetDup, @CustomerName, @CustomerAdd; END -- 关闭并释放游标资源 CLOSE CustomerCursor; DEALLOCATE CustomerCursor; END
代码说明:
- 外层游标用来遍历源表的每一条记录,把字段值暂存到变量中;
- 内层WHILE循环负责控制重复插入的次数,循环次数严格等于
GetDup的数值; SET NOCOUNT ON用来屏蔽插入操作返回的“影响行数”提示,让存储过程的执行输出更简洁。
测试验证:
用你提供的输入数据测试:
-- 先插入初始测试数据 INSERT INTO Customers (GetDup, CustomerName, CustomerAdd) VALUES (1, 'John', '123 SomeWhere'), (2, 'Bob', '987 SomeWhere'); -- 执行存储过程生成重复记录 EXEC InsertDuplicateRecords; -- 查询最终结果 SELECT * FROM Customers;
就能得到你期望的输出:
| Getdup | CustomerName | CustomerName |
|---|---|---|
| 1 | John | 123 SomeWhere |
| 2 | Bob | 987 SomeWhere |
| 1 | John | 123 SomeWhere |
| 2 | Bob | 987 SomeWhere |
| 2 | Bob | 987 SomeWhere |
注意事项:
- 如果你的表有主键或唯一约束,需要先调整约束(比如把主键设为自增字段),否则插入重复记录会触发约束报错;
- 如果源表数据量极大,游标+循环的效率会低于集合式操作(比如CTE+数字表),但这是完全满足你“必须使用循环语句”要求的方案;
- 可以根据你的实际表名、字段名调整存储过程中的对应内容。
内容的提问来源于stack exchange,提问作者Jong Lee
相关产品推荐
相关产品推荐

