Chinaunix首页 | 论坛 | 博客
  • 博客访问: 249531
  • 博文数量: 91
  • 博客积分: 2016
  • 博客等级: 大尉
  • 技术积分: 820
  • 用 户 组: 普通用户
  • 注册时间: 2008-07-08 23:25
文章分类

全部博文(91)

文章存档

2011年(6)

2010年(6)

2009年(34)

2008年(45)

我的朋友

分类:

2008-07-08 23:54:28

有条件的分步删除数据表中的记录删除时,在使用delete语句数据库是要做日志记录的,以便将来可以恢复数据,
删除上百万条数据时,十分缓慢 ,对于删除大批量的数据总结了以下几种方式进行批量删除:
方法一:
create or replace procedure delete_table
is
i number(10);
begin
  for x in (select * from emp where DEPTNO like 'a%')
  loop
      delete emp where emp.id = x.id
      i:=i+1;
      if i>1000 then
         commit;
         i:=0;
      end if;
  end loop;
exception
    when others then
         dbms_out.put_line(sqlcode);
         rollback;
end delete_table;


方法二:
DECLARE
CNT NUMBER(10):=0;
I NUMBER(10);
BEGIN
SELECT COUNT(*) INTO CNT FROM emp where DEPTNO like 'a%'

FOR I IN 1..TRUNC(CNT/500)+1 LOOP
DELETE FROM emp where DEPTNO like 'a%' AND ROWNUM<=1000;
COMMIT;
END LOOP;
END;

方法三:
create or replace procedure deleteTab
  /**
   ** Usage: run the script to create the proc deleteTab
   **        in SQL*PLUS, type "exec deleteTab('Foo','ID>=1000000','3000');"
   **        to delete the records in the table "Foo", commit per 3000 records.
   **       Condition with default value '1=1' and default Commit batch is 10000.
   **/
  (
    p_TableName    in    varchar2,    -- The TableName which you want to delete from
    p_Condition    in    varchar2 default '1=1',    -- Delete condition, such as "id>=100000"
    p_Count        in    varchar2 default '10000'    -- Commit after delete How many records
  )
  as
   pragma autonomous_transaction;
   n_delete number:=0;
  begin
   while 1=1 loop
     EXECUTE IMMEDIATE
       'delete from '||p_TableName||' where '||p_Condition||' and rownum <= :rn'
     USING p_Count;
     if SQL%NOTFOUND then
     exit;
     else
          n_delete:=n_delete + SQL%ROWCOUNT;
     end if;
     commit;
   end loop;
   commit;
   DBMS_OUTPUT.PUT_LINE('Finished!');
   DBMS_OUTPUT.PUT_LINE('Totally '||to_char(n_delete)||' records deleted!');
  end;
  /
方法四:把要保留的数据放在一个临时表里,truncate table后再放回来
       举例(省略)

删除重复记录
方法一:delete from table1 a where rowid!=(select max(rowid) from table1 b where a.id=b.id );
方法二:delete from table1
          where rowid in (select rowid
                              from (select rowid ,
                                    row_number() over(partition by field1,field2.... order by rowid )rn from table1 ) where rn<>1);

方法三:创建临时表把不重复的数据DISTINCT 后放在临时表里,然后DROP 掉‘原表’,再 RENAME ‘临时表’ TO ‘原表’ 就OK了!

其中方法一适合数据量小的删除,方法二适合数据量稍大表的删除,方法三适合重复的数据量特别大的删除。方法二还可以根据某个字段进行删除,只保留
阅读(889) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~