首页 > 解决方案 > oracle使用rownum从表中删除数据

问题描述

我有一个从 table1 中删除数据的过程。该过程的五个实例同时运行并且全部运行没有任何错误/异常。但是,table1 中仍有许多记录 EndTime <= v_purgedate。请帮忙。

declare
 rowcount1 NUMBER;
begin
    LOOP
        delete table1 eh
            where eh.EndTime <= v_purgedate
            and rownum <= 30000 ;
        rowcount1 := rowcount1 + sql%rowcount;      
        commit;
        exit when rowcount1=0;
rowcount1=0;
    END LOOP;
end;
/

标签: oracleplsql

解决方案


你正在尝试做所谓的“自己做并行”,而不是如果你问得好,Oracle 可以自己做的并行处理。

有一个名为 DBMS_PARALLEL_EXECUTE 的包可以为您执行此操作。您将数据拆分为块(基于 ROWID 或数字),然后调用 RUN_TASK 过程以串行或并行方式处理每个块。每个块有一个提交。

这是一个每次提交删除 30,000 行的演示。一、测试数据:

SQL> create table table1(endtime) as
  2  select trunc(sysdate) - level/24 from dual
  3  connect by level <= 240000;

Table TABLE1 created.

SQL> insert into table1 select * from table1;

240,000 rows inserted.

SQL> insert into table1 select * from table1;

480,000 rows inserted.

SQL> insert into table1 select * from table1;

960,000 rows inserted.

SQL> select count(*) from table1;

  COUNT(*)
----------
   1920000

现在,这里是代码:

SQL> declare
  2    l_task_name varchar2(128) := 'Delete_TABLE1';
  3    l_sql_chunk clob := q'§
  4  select date '2100-01-01' - min(endtime) start_id,
  5    date '2100-01-01' - max(endtime) end_id,
  6    chunk
  7  from (
  8    select endtime,
  9      ceil(row_number() over(order by endtime) / 30000) chunk
 10    from table1 where endtime < sysdate - 8000
 11  )
 12  group by chunk
 13  §';
 14    l_sql_run clob := q'§
 15  delete from table1
 16  where endtime between
 17    date '2100-01-01' - :start_id and
 18    date '2100-01-01' - :end_id
 19  §';
 20    l_boolean boolean := false;
 21    task_not_found EXCEPTION;
 22    PRAGMA EXCEPTION_INIT(task_not_found, -29498);
 23  begin
 24    begin
 25      DBMS_PARALLEL_EXECUTE.DROP_TASK (l_task_name);
 26    exception when task_not_found then null;
 27    end;
 28    DBMS_PARALLEL_EXECUTE.CREATE_TASK (l_task_name);
 29    DBMS_PARALLEL_EXECUTE.CREATE_CHUNKS_BY_SQL (
 30      task_name => l_task_name,
 31      sql_stmt => l_sql_chunk,
 32      by_rowid => l_boolean
 33    );
 34    DBMS_PARALLEL_EXECUTE.RUN_TASK (
 35      task_name => l_task_name,
 36      sql_stmt => l_sql_run,
 37      language_flag => 1,
 38      parallel_level => 0 -- 0 for serial, 2+ for parallel
 39    );
 40  end;
 41  /

推荐阅读