我需要以下查询的帮助。如何使用 while 循环将表 1 中的所有行以 10 为一组插入到表 2 中(表 1 和表 2 是相同的表,表 1 有 500 条记录)。我想避免使用临时表。
我正在尝试批量加载,类似于以下内容:
Declare @rowcount int
while @rowcount > 0
begin
Insert into table2(id, name, address)
Select top 10 id,name, address from table 1)
set @rowcount = @rowcount +1
end
如果您想一次性通过 SSMS 执行此操作,请执行以下操作
INSERT INTO table2
SELECT TOP 10
*
FROM table1 t1
WHERE NOT EXISTS (SELECT
1
FROM table2 t2
WHERE t2.id = t1.id)
GO 10 -- will loop for 10 times
如果超过存储的脚本,则删除
GO 10
并用 while 循环包装插入查询
如果您的
id
是您的主键,您可以考虑此查询。
通过使用
row_number()
将确保您不会根据您的唯一密钥复制您的记录
where t2.rn between (@rowcount * 10) + 1 and (@rowcount*10) + 10
这是您的完整脚本
Declare @rowcount int
set @rowcount = 0
while @rowcount > 0
begin
Insert into table2(
id,
name,
address)
select t1.id, t1.name, t1.address
from table1
inner join
(Select row_number() over (order by id) as rn, id
from table1) t2 on t2.id = t1.id
where t2.rn between (@rowcount * 10) + 1 and (@rowcount*10) + 10
set @rowcount = @rowcount + 1
end
一个选项是创建一个带有状态列的临时表来指示那些未处理的数据,然后使用它来计算未处理的数据并指示是否有新的批次要处理。
Declare @rowcount int = 1
Select *, cast(0 as int) as status
into #tmpToProcess
from table1
while @rowcount > 0
begin
begin transaction
update top(10) #tmpToProcess
set status = 1 --inProcess
Insert into table2(id, name, address)
Select top 10 id,name, address from #tmpToProcess where status = 1
update #tmpToProcess
set status = 1 --inProcess
where status = 2 --Processed
commit transaction
select @rowcount = count(*)
from #tmpToProcess
where status = 0
end
我知道它有点长,但这样您就可以以 10 条记录为一组进行处理,并准确跟踪已处理的记录和待处理的记录。只需添加一个 try catch 即可将其四舍五入。
事情从你的角度来看很混乱。
当只有500条记录时,为什么要批量插入并使用
While Loop
。
批量插入适合数百万条记录。
你必须说出什么是
Unique Key
。在我的脚本中我假设是ID
。
declare @Batch int=12
declare @PIndex int=1
Declare @TotalRecord int=100
Select @TotalRecord=count(id) from table1
declare @PageNo int=case when @TotalRecord%@Batch=0 then @TotalRecord/@Batch else (@TotalRecord/@Batch)+1 end
--select @PageNo
While (@PIndex<=@PageNo)
begin
insert into table2
select * from table1 t1
where not exists(select 1 from table2 t2 where t1.id=t2.id)
ORDER BY t1.id OFFSET @Batch * (@PIndex - 1) ROWS
FETCH NEXT @Batch ROWS ONLY;
set @PIndex=@PIndex+1
end
where not exists(select 1 from table2 t2 where t1.id=t2.id)
这是为了预防措施,因为我们不知道桌子设计。
代码未经测试。