批量插入while循环

时间:2019-09-17 00:59:19

标签: sql sql-server tsql batch-processing

我需要以下查询的帮助。如何使用while循环将表1到表2的所有行以10为批插入(表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

4 个答案:

答案 0 :(得分:0)

如果您想一次性通过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循环包装插入查询

答案 1 :(得分:0)

如果您的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

答案 2 :(得分:0)

一种选择是创建一个带有状态列的临时表,以指示那些未处理的临时表,然后使用该表对未处理的计数,并指示是否有新的批次要处理。

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条记录为一组进行处理,并准确跟踪已处理的记录和未决的记录。只是可以添加一个尝试捕获来对其进行四舍五入。

答案 3 :(得分:0)

从头到尾都感到困惑。

当只有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)  用于预防措施,因为我们不了解表格设计。

代码未经测试。