我想使用PL/SQL删除大量记录。这些记录由 DATE 字段标识,该字段标识上次修改记录的时间。我不想消耗太多资源,因此我认为应该限制要删除的记录数量,在我看来,伪列 ROWNUM 可以满足此目的。然后,我检查受更新影响的行数并重复,直到影响的行数为 0。
我正在寻找有关执行此操作的最佳实践的建议。我还担心我收到的警告:
“包含 DML 语句的循环应重构为使用 BULK COLLECT 和 FORALL。”
但是当我用谷歌搜索这个主题时,似乎这并不适用于我想做的事情——或者是吗?
欢迎您提出意见和建议。
CREATE OR REPLACE PACKAGE BODY MY_PURGE
AS
PROCEDURE PURGE_MY_TABLE (v_Cut_Off_Date IN DATE,
C_MAX_DELETE IN NUMBER,
DEL_COUNT OUT NUMBER)
IS
v_RECORDS_DELETED NUMBER := 0;
V_DONE BOOLEAN := FALSE;
BEGIN
DEL_COUNT := 0;
WHILE NOT V_DONE
LOOP
DELETE FROM MYTABLE
WHERE UPDT_TIMESTMP < v_Cut_Off_Date
AND ROWNUM <= C_MAX_DELETE;
v_RECORDS_DELETED := SQL%ROWCOUNT;
DEL_COUNT := DEL_COUNT + v_RECORDS_DELETED;
IF (v_RECORDS_DELETED = 0)
THEN
V_DONE := TRUE;
END IF;
COMMIT;
END LOOP;
END;
Thanks
您担心消耗哪些资源?单个DELETE
声明将是最有效的方法*。假设这是需要定期完成的事情,那么数据库的大小确实应该根据以下方面进行适当调整:UNDO
表空间允许您执行单个DELETE
.
实际上,退一步来说,最有效的方法是按UPDT_TIMESTMP
并删除旧分区。但分区是企业版许可证之外的额外成本选项,并且对表进行分区可能会对系统产生其他影响。
如果您确实需要通过临时提交批量删除行,那么这似乎是一个非常合理的实现。我真的只会考虑这个,如果单身DELETE
声明占用了我每晚处理窗口的很大一部分,我担心DELETE
几个小时后可能会失败,强制回滚并重新启动整个过程。批量删除比单个删除慢DELETE
通常,但重新启动会更容易。
使用建议BULK COLLECT
and FORALL
在这种特殊情况下没有意义。它适用于一种更常见的情况,即有人从一个或多个源表中选择数据,在 PL/SQL 中进行一些处理,然后将数据写入目标表。通过批量操作而不是通过缓慢的逐行处理来实现这一点会更有效。但如果单独进行的话,效率会更高INSERT ... SELECT
.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)