PL/SQL - 不更新更改的行

PL/SQL - do not update changed rows

我计划对我巨大的 table(超过十亿行)进行长时间 运行 更新。此更新会将一列的值乘以固定数字。

问题是在我的更新过程中(可能会持续几个小时)肯定会有短事务更新某些行,这些行将具有不应更新的正确值,尽管它们仍然满足我的更新条件.

所以问题是 - 如何跳过(不更新)在我的长 运行 更新事务之外更新的行?

一种方法是使用 FOR UPDATE SKIP LOCKED 这样其他会话将无法选择已经选择进行更新的行。

例如,

会话 1:

SQL> SELECT empno, deptno
  2    FROM emp  WHERE
  3   deptno = 10
  4  FOR UPDATE NOWAIT;

     EMPNO     DEPTNO
---------- ----------
      7782         10
      7839         10
      7934         10

SQL>

第 2 节:

SQL> SELECT empno, deptno
  2    FROM emp  WHERE
  3   deptno in (10, 20)
  4  FOR UPDATE NOWAIT;
  FROM emp  WHERE
       *
ERROR at line 2:
ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired

现在让我们跳过会话 1 锁定的行

SQL> SELECT empno, deptno
  2    FROM emp  WHERE
  3   deptno IN (10, 20)
  4  FOR UPDATE SKIP LOCKED;

     EMPNO     DEPTNO
---------- ----------
      7369         20
      7566         20
      7788         20
      7876         20
      7902         20

SQL>

因此,部门 = 10 被会话 1 锁定,然后部门 = 20 被会话 2 锁定。

我已经解决了类似你的问题,但我的 table 不像你的那么大。

我重新设计了 table,添加了 2 列。

created_date: A Trigger put sysdate when insert data.

modified_date: A Trigger put sysdate when update data.

然后我可以在我的 where 子句中使用 created_date 或 modified_date。

示例:

UPDATE TABLE table_name
SET column_name = 'values'
WHERE created_date < SYSDATE;

希望对您有所帮助。

哦,我完全忘记了这个问题。 因此,我最终通过将当前行的副本保存到另一个 table 来制作当前行的快照(我必须只更新满足给定条件的那些行)。之后,我更新了未更改其值的行(使用合并)。