2016-10-03 310 views
1

什么是最有效的方式来更新sql server中的表,以便在单个事务中放置10k记录的限制?批量Sql更新

我通过在while循环中添加它来阅读关于top和ROWCOUNT的方法。那些更有效?或者如果你知道替代有效的方式,请分享。谢谢。

+0

你现在在使用什么脚本? – mfredy

+0

不要使用ROWCOUNT来控制如何使用UPDATE语句更新行。它的用法已被弃用,并将在未来停止工作。 https://msdn.microsoft.com/en-us/library/ms188774.aspx –

+0

您是否打算一次更新每行10,000行或仅排在前10000行? – ZLK

回答

0

这里是不使用set rowcount

-- prepare test data 
use tempdb 
drop table dbo.t; 
create table dbo.t (a int identity, b int) 
go 
insert into dbo.t (b) 
values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10), (11); 
go 

-- assume we do 3 records per time, put 10000 here if you wnat 10K records 
-- also the update is just to update column [b] to [b] * 2, here is the code 

declare @N int = 3; -- do a batch of @N records 

declare @i int = 0, @max_loop int; 

select @max_loop = count(*)/@N from dbo.t 

-- the first batch may include records <= @N-1 and the last batch may include records <= @N 
while (@i <= @max_loop) 
begin 

    ; with c as (
    select rnk=ROW_NUMBER() over (order by a)/@N, a, b from dbo.t 
    ) 
    update c set b = b*2 -- doule b 
    where rnk = @i; 

    set @i = @i + 1; 
end 
go 
-- check the result 
select * from dbo.t 
-1

您可以用以下方法尝试一个可能的方法:

WHILE (1=1) 
BEGIN 
    BEGIN TRANSACTION 
    UPDATE TOP (10000) XXX 
    SET XXX.YYY = <ValueToUpdate> 
    FROM XXX -- Update 10000 nonupdated rows 
    WHERE <condition> -- make sure that condition makes sure that it does not become infinite loop 
    IF @@ROWCOUNT = 0 
    BEGIN 
     COMMIT TRANSACTION 
     BREAK 
    END 
    COMMIT TRANSACTION 
END 

编辑

更新组织的所有员工,使确定它不会成为无限循环。在这里,我正在更新员工记录的修改日期。

DECLARE @updatedids table(id int) 
WHILE (1=1) 
BEGIN 
    BEGIN TRANSACTION 
    UPDATE TOP(10000) a  
    SET a.ModifiedDate = GETDATE() 
    OUTPUT inserted.BusinessEntityID INTO @updatedids 
    FROM HumanResources.Employee a 
LEFT JOIN @updatedids u 
    ON a.BusinessEntityID = u.id 
    WHERE u.id IS NULL 
    -- Update 10000 nonupdated rows 
    IF @@ROWCOUNT = 0 
    BEGIN 
     COMMIT TRANSACTION 
     BREAK 
    END 
    COMMIT TRANSACTION 
END 
+0

这将是一个死循环,因为可以连续更新相同的10000行。 (至少在SQL服务器,我测试) – jyao

+0

我错过了WHERE子句。抱歉。我已经更新了代码。我主要关注逻辑。 –

+0

对于表格上的GENERIC更新,有时可能不存在有效的条件来筛选出已更新的条件。例如,假设我们有一张有两列的表[employeesee_id]和[薪金],也可以这么说,现在我们要给所有人增加10%,现在假设这张表有100万行,我们想在10K /块更新中更新此表,我们如何才能想出一个好的where子句? – jyao