0

我希望每 1000 行提交一次,直到所有记录都被删除,我们有超过一百万条记录要删除。

起初:

private static final String DELETE_OLD_REPORTS_FROM_REPORTING =
-            "DELETE FROM A_REPORTING\n" +
-            "WHERE ID IN(" +
-            "SELECT ID FROM A_REPORTING\n" +
-            "WHERE STATUS = 'LOADED'\n" +
-            "AND CREATE_DT < TO_DATE(:createdDate, 'dd-mon-yyyy'))";

我正在考虑做这样的事情:

"BEGIN\n" +
                "LOOP\n" +
                    "DELETE FROM A_REPORTING\n" +
                    "WHERE ID IN(" +
                    "SELECT ID FROM A_REPORTING\n" +
                    "WHERE STATUS = 'LOADED'\n" +
                    "AND CREATE_DT < TO_DATE(:createdDate, 'dd-mon-yyyy')\n+" +
                    "AND ROWNUM <= 10000);\n" +
                    "EXIT WHEN SQL%rowcount < 9999;\n" +
                    "COMMIT;\n" +
                "END LOOP;\n"+
            "COMMIT;\n" +
            "END";

但是,有没有更好的方法来做到这一点?这是因为我们收到了 ORA-01555 错误:

ORA-01555: 快照太旧: 名称为 "%segname" 的回滚段号 %n 太小。

4

2 回答 2

1

这听起来非常适合批量收集!

declare

  d_created_date   date   := to_date(:createddate, 'dd-mon-yyyy'); -- define :createddate here

  -- get all rows you want to delete
  cursor cur_delete_records is
  select r.rowid 
    from a_reporting r
   where r.status = 'LOADED'
     and r.create_dt < to_date(d_created_date, 'dd-mon-yyyy');

  -- collection to store rows
  type t_delete_records   is table of cur_delete_records%rowtype;
  rec_delete_records      t_delete_records;

begin

  open cur_delete_records;
    loop
      fetch cur_delete_records
      bulk collect into rec_delete_records
      limit 1000; -- here's the 1,000 record max per loop
      exit when nvl(rec_delete_records.count, 0) = 0;

      forall x in rec_delete_records.first .. rec_delete_records.last

        delete from a_reporting r
         where r.rowid = rec_delete_records(x).rowid;

        commit;

    end loop;
  close cur_delete_records;

end;
/
于 2018-07-03T18:47:17.090 回答
0

您可以使您的撤消表空间足够大,以便原始删除语句的所有数据更改都可以保留在撤消中。然后您可以增加您的 undo_retention 参数,使其比原来的删除语句运行所需的时间更长。因此,如果删除需要 1 小时运行,则将撤消保留设置为 4 小时并不断增加撤消表空间的大小,直到在运行删除时没有得到 ORA-01555。除非行非常大,否则删除 100 万行并不算多。您应该能够通过撤消来阻止 ORA-01555。

鲍比

于 2018-07-03T19:47:26.697 回答