是否可以在SQL Update语句中添加TOP或某种分页?
我有一个UPDATE
查询,结果如下:
UPDATE XXX SET XXX.YYY = #TempTable.ZZZ
FROM XXX
INNER JOIN (SELECT SomeFields ... ) #TempTable ON XXX.SomeId=#TempTable.SomeId
WHERE SomeConditions
此更新将影响数百万条记录,我需要批量执行此操作。像当时的100.000(排序无关紧要)
最简单的方法是什么?
答案 0 :(得分:19)
是的,我相信您可以在更新声明中使用TOP,如下所示:
UPDATE TOP (10000) XXX SET XXX.YYY = #TempTable.ZZZ
FROM XXX
INNER JOIN (SELECT SomeFields ... ) #TempTable ON XXX.SomeId=#TempTable.SomeId
WHERE SomeConditions
答案 1 :(得分:5)
您可以使用SET ROWCOUNT { number | @number_var }
限制在停止特定查询之前处理的行数,例如:
SET ROWCOUNT 10000 -- define maximum updated rows at once
UPDATE XXX SET
XXX.YYY = #TempTable.ZZZ
FROM XXX
INNER JOIN (SELECT SomeFields ... ) #TempTable ON XXX.SomeId = #TempTable.SomeId
WHERE XXX.YYY <> #TempTable.ZZZ and OtherConditions
-- don't forget about bellow
-- after everything is updated
SET ROWCOUNT 0
我已将XXX.YYY <> #TempTable.ZZZ
添加到where
子句,以确保您不会更新两次已更新的值。
将ROWCOUNT
设为0
关闭限制 - 不要忘记。
答案 2 :(得分:4)
您可以执行以下操作
declare @i int = 1
while @i <= 10 begin
UPDATE top (10) percent
masterTable set colToUpdate = lt.valCol
from masterTable as mt
inner join lookupTable as lt
on mt.colKey = lt.colKey
where colToUpdate is null
print @i
set @i += 1
end
--one final update without TOP (assuming lookupTable.valCol is mostly not null)
UPDATE --top (10) percent
masterTable set colToUpdate = lt.valCol
from masterTable as mt
inner join lookupTable as lt
on mt.colKey = lt.colKey
where colToUpdate is null
答案 3 :(得分:3)
根据您更改表格数据结构的能力,我建议您在表格中添加一个可以容纳某种批次标识符的字段。 IE浏览器。如果你每天都这样做,它可以是一个日期戳,一个增量值或基本上你可以为你的批次制作的任何值。如果采用增量方法,则更新将为:
UPDATE TOP (100000) XXX SET XXX.BATCHID = 1, XXX.YYY = ....
...
WHERE XXX.BATCHID < 1
AND (rest of WHERE-clause here).
下次,您将设置BATCHID = 2和WHERE XXX.BATCHID < 2
如果要重复这样做,您可以在BATCHID上设置索引并减少服务器上的负载。
答案 4 :(得分:0)
DECLARE @updated_Rows INT;
SET @updated_Rows = 1;
WHILE (@updated_Rows > 0)
BEGIN
UPDATE top(10000) XXX SET XXX.YYY = #TempTable.ZZZ FROM XXX
INNER JOIN #TempTable ON XXX.SomeId=#TempTable.SomeId
WHERE SomeConditions
SET @updated_Rows = @@ROWCOUNT;
END