Oracle SQL Update Query,循环以限制一次更新的行

时间:2014-06-27 14:24:16

标签: sql oracle loops limit rows

我有一个查询,用于更新新列的所有过去历史记录。它从具有相应ID的源表中提取值。它还将更新时间与当前时间进行比较,当前时间可能会发生变化但现在保证会在每一行上运行。

UPDATE table1
SET table1.comment = 
   (SELECT table2.comment
    FROM table2
    WHERE table1.ID = table2.ID)
WHERE(SELECT table2.updateTime
FROM table2
WHERE table1.ID = table2.ID) < sysdate

生产中有数百万行,我需要将其限制在循环中,或者只需要一次更新这么多行。我对SQL很新,并且无法找到有关循环如何限制更新行数的任何文档。循环如何知道正在使用的表中的行?

1 个答案:

答案 0 :(得分:0)

有几件事......首先,如果你的表有主键,那么这可能是首选的更新方法:

update (
  select
    t1.comment c1, t2.comment c2
  from
    table1 t1,
    table2 t2
  where
    t1.id = t2.id and
    t2.updateTime < sysdate
)
set
  c1 = c2

其次,假设updateTime意味着我认为它意味着什么,它不会总是小于sysdate吗?是否有理由这样做?

第三,为了尽量减少不必要的更新,我想你可以添加这个。假设只有一部分行需要更新,这应该会极大地影响性能。

update (
  select
    t1.comment c1, t2.comment c2
  from
    table1 t1,
    table2 t2
  where
    t1.id = t2.id and
    t2.updateTime < sysdate and
  ((t1.comment is null and t2.comment is not null) or
   (t1.comment is not null and t2.comment is null) or
    t1.comment != t2.comment)
)
set
  c1 = c2

最后,我并不是说Loop永远不会有所帮助,但我说这通常是错误的做法。 Oracle已经过调整以做这种事情。如果您的更新查询速度很慢,那么在程序循环中包装它会让它运行得更快。对于经过良好调整的Oracle数据库,更新数百万行不应该是一个问题。

我理解这样做背后的想法,这在人类世界中是有意义的。我自己尝试过只是为了让一个聪明的甲骨文男人告诉我我错了。当他调整更新查询时,结果证明他是对的。