DB2中的正确更新语句,以避免事务日志已满

时间:2015-01-29 02:06:12

标签: transactions db2 db2-luw

我想更新一个在unix上运行的DB2中有超过200万条记录的表。有没有办法以批量大小更新一次5000行?在Sybase中,我可以使用“set rowcount 5000”,如下所示:

set rowcount 5000
while ( 1=1 )
begin
 begin tran
  update X set ... where ...
  if (@@error != 0)
    begin
        rollback tran
        return 1
    end
 commit tran

if(  @@rowcount < 5000 ) break
end

set rowcount 0

如何在DB2中执行此操作?目的是尽量避免事务日志完全导致更新失败。

1 个答案:

答案 0 :(得分:2)

您有两个选项,都涉及复合SQL。如果有一种方法可以确定哪些记录已更新,哪些记录没有更新,您可以这样写:

BEGIN
  WHILE EXISTS (SELECT 1 FROM yourtable WHERE <condition to find records to update>)
  DO
    UPDATE (SELECT * FROM yourtable WHERE <condition> FETCH FIRST 5000 ROWS ONLY)
      SET ...; -- updating 5000 rows at a time
    COMMIT;
  END WHILE;
END

如果您无法轻易区分更新的行和尚未更新的行,则可以执行以下操作:

BEGIN
  DECLARE i INT DEFAULT 0;
  FOR l AS cur CURSOR WITH HOLD FOR 
   SELECT * FROM yourtable WHERE ... FOR UPDATE
  DO
    UPDATE yourtable SET ... WHERE CURRENT OF cur;
    SET i = i + 1;
    IF MOD(i, 5000) = 0 THEN
      COMMIT; -- every 5000 rows
    END IF;
  END FOR;
  COMMIT; -- last set, may be less than 5000 rows
END

后一个选项显然效率较低,因为它会逐行更新行,而不是5000行。