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 来制作当前行的快照(我必须只更新满足给定条件的那些行)。之后,我更新了未更改其值的行(使用合并)。
我计划对我巨大的 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 来制作当前行的快照(我必须只更新满足给定条件的那些行)。之后,我更新了未更改其值的行(使用合并)。