-1

贾斯汀,根据你的建议,我在这里添加了循环..

无论如何我们可以调整这个程序吗?我还没有测试。

在这里,我们只是从主表和子表中删除 90 天历史记录之前的记录。假设表有超过 20k 条记录要删除。在这里我为每条 5k 记录提交。如果我在这里错了,请告诉我?

create or replace 
Procedure PURGE_CLE_ALL_STATUS 
 ( days_in IN number ) 
  IS 
  LV_EXCEPTIONID NUMBER;    
i number := 0;  


cursor s1 is 
        select EXCEPTIONID 
          from EXCEPTIONREC --- master table 
          where TIME_STAMP < (sysdate -days_in); 

BEGIN  

for c1 in s1 loop

     delete from EXCEPTIONRECALTKEY   -- child table 
     where EXCEPTIONID =c1.EXCEPTIONID ; 

     delete from EXCEPTIONREC 
     where EXCEPTIONID =c1.EXCEPTIONID; 

     i := i + 1;              

     if i > 5000 then      
      commit;         
      i := 0;      
     end if;  

end loop;  


commit;      

close S1; 
EXCEPTION 
WHEN OTHERS THEN 
      raise_application_error(-20001,'An error was encountered - '|| 
                                      SQLCODE||' -ERROR- '||SQLERRM); 
END; 
/
4

2 回答 2

3

而不是游标..您可以直接在删除语句中给出条件..

像下面 -

create or replace
Procedure PURGE_CLE_ALL_STATUS
 ( days_in IN number )
  IS
  LV_EXCEPTIONID NUMBER;   

BEGIN    

     delete from EXCEPTIONRECALTKEY   -- child table
     where EXCEPTIONID = -- (1)
          (select EXCEPTIONID
          from EXCEPTIONREC --- master table
          where TIME_STAMP < (sysdate -days_in));

     delete from EXCEPTIONREC
     where EXCEPTIONID = --(2)
          (select EXCEPTIONID
          from EXCEPTIONREC --- master table
          where TIME_STAMP < (sysdate -days_in));

commit;     
end if;
close c1;
END;
/

我完全同意 Justin Cave .. 他给出了很好的观点 .. 如果您从光标中获得多行 .. 您可以使用at (1) 和 (2)in来代替。=

于 2012-05-15T15:04:38.303 回答
0

“从主表和子表中删除 90 天历史记录之前的记录”

为了获得全部性能优势,您应该实现分区表。当然,这种设计更改可能不会改变您的应用程序。

您的用例是定期删除数据。您尝试创建每日或每周分区,将新数据存储在较新的分区中并定期删除旧分区。

当前的删除方式会遇到性能瓶颈,因为您尝试删除超过 90 天的数据。假设每天有 10,000 条记录,那么到第 90 天将有 90*10000。从 9000 万条记录中定位和删除几条记录总是会很慢并产生其他一些锁定问题。

于 2014-10-13T07:30:52.263 回答