【问题标题】:Need help to create purging operation executing in loop需要帮助来创建循环执行的清除操作
【发布时间】:2023-04-08 00:03:01
【问题描述】:

我将运行一个 pl/sql 块来删除表中所有超过 30 天的数据。

情况是这样的:

它将一次删除 200k 数据,删除 200k 数据后,我必须等待 10-15 秒。该表中有大约 1 亿条记录。我想在自动化脚本中完成整个删除过程。

DECLARE
   CURSOR c6
   IS
      SELECT                                               /*+parallel(a,32)*/
            a.rowid,a.*
        FROM EB_O.CCO_DIR_CONTRS_ES_GG a
       WHERE a.GG_CREATE_DATE < SYSDATE-30
       AND ROWNUM <=200001;

   TYPE contact_point_id_tab IS TABLE OF c6%ROWTYPE
                                   INDEX BY PLS_INTEGER;

   l_contact_point_id_tab   contact_point_id_tab;
BEGIN
   OPEN c6;

   LOOP
      FETCH c6
      BULK COLLECT INTO l_contact_point_id_tab
      LIMIT 10000;

      EXIT WHEN l_contact_point_id_tab.COUNT = 0;

      IF l_contact_point_id_tab.COUNT > 0
      THEN
         FORALL i
             IN l_contact_point_id_tab.FIRST .. l_contact_point_id_tab.LAST
            DELETE FROM  EB_O.CCO_DIR_CONTRS_ES_GG
                            WHERE rowid =l_contact_point_id_tab (i).rowid;

         COMMIT;
      END IF;

      l_contact_point_id_tab.delete;
   END LOOP;
END;

这是我写的上面的plsql块。如何在多个循环中执行此操作,并且在每个循环之后将有 10-15 秒的等待期,并且对于下一个 200k 数据将再次进行删除操作。循环将继续,直到所有数据都被删除。

注意:对于等待期,DBMS_LOCK.sleep 没有授权

【问题讨论】:

标签: oracle plsql plsql-package


【解决方案1】:

我不会通过循环游标来做到这一点。相反,我会这样做:

begin
  loop
    delete FROM EB_O.CCO_DIR_CONTRS_ES_GG
    WHERE GG_CREATE_DATE < SYSDATE-30
    AND ROWNUM <=200000;

    exit when sql%rowcount = 0;

    commit;

    dbms_lock.sleep(10);
  end loop;
end;
/

这样,您可以避免潜在的快照太旧错误(因为您已经提交了游标提取循环),并且您不再将信息提取到内存中以传回数据库,从而提高效率.

【讨论】:

    【解决方案2】:

    如果您无法使用睡眠功能,请自行创建。 将以下查询的输出存储在变量中,创建一个循环,当 sysdate 等于存储在变量中的值时退出。

    select sysdate+(10 / (24*60*60)) from dual;
    

    此外,您可以将秒作为输入变量并在查询中传递相同的值,而不是硬编码 10。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-10-15
      • 2012-01-15
      • 1970-01-01
      • 2013-05-24
      • 1970-01-01
      • 1970-01-01
      • 2021-08-25
      • 2020-08-22
      相关资源
      最近更新 更多