使用联接更新SQL数据块
我的数据库中有两个表,一个包含关于客户机的数据(称为客户机),另一个表包含clientID、Guid、AddedTime和IsValid(称为ClientsToUpdate) ClientID与clients表相关,Guid是唯一标识符,AddedTime是记录添加到表中的时间,IsValid是指示此ClientID是否更新的位 我想做的是更新ClientsToUpdate中的所有客户机,问题是,ClientsToUpdate表包含超过80000条记录,并且我遇到了死锁 我想我能做的是,使用while循环或类似的方法,一次更新2000个客户端 我的存储过程如下所示:使用联接更新SQL数据块,sql,stored-procedures,sql-update,Sql,Stored Procedures,Sql Update,我的数据库中有两个表,一个包含关于客户机的数据(称为客户机),另一个表包含clientID、Guid、AddedTime和IsValid(称为ClientsToUpdate) ClientID与clients表相关,Guid是唯一标识符,AddedTime是记录添加到表中的时间,IsValid是指示此ClientID是否更新的位 我想做的是更新ClientsToUpdate中的所有客户机,问题是,ClientsToUpdate表包含超过80000条记录,并且我遇到了死锁 我想我能做的是,使用wh
UPDATE client SET LastLogin=GETDATE()
FROM Clients client
JOIN ClientsToUpdate ctu ON client.ID = ctu.ClientID;
知道我该怎么做吗
declare @done table (ClientID int primary key)
while 1=1
begin
update top (2000) c
set lastlogin = getdate()
output deleted.id into @done
from Clients c
join ClientsToUpdate ctu
on c.id = ctu.ClientID
where not exists
(
select *
from @done d
where d.ClientID = ctu.ClientID
)
if @@rowcount = 0
break
end
如果遇到死锁,分块更新可能会减少错误(假设您仔细管理事务并提交块更新),但不会解决死锁。IMHO您应该调查锁问题并找出死锁的原因基本上,他正在更新查询中满足where条件的前2000行,直到遍历了所有80000行。他将更新行的ID存储到@done中以进行检查(嵌套的select*)。当@rowcount=0时,这意味着没有任何内容被更新,因此没有任何内容需要更新。是时候打破循环了。Andomar,这是应该更新的。ids而不是删除的。ids吗?@Yatrix:由于
id
列没有更改,您可以同时使用删除的
(更新前的列值)和插入的
(更新后的列值。)我不认为有一个更新的
特殊表格。有趣。混乱。呵呵。