在一个ORACLE数据库运行过程中,有时候会遇到要批量删除数据的情况,如一个保存历史数据的表中有大量的数据已经不需要保留,要将这部分数据删除。
以下就这种情况可以采取的方法进行讨论。

1、使用TRUNCATE命令进行删除。
如果是整个表的数据都要删除的话,使用TRUNCATE TABLE命令是理想的选择。它删除了表中的所有数据,并且因为不写REDO LOG FILE,所以速度很快。删除的同时,表的索引和约束条件仍然存在。这种方法适用于ORACLE的各个版本。但是当要删除的数据只是表中的一部分时,这种方法便行不通了。

2、直接进行DELETE操作。
直接使用DELETE命令进行删除,如果删除的数据量较大时,可能导致回滚段出错。这是因为在删除数据的过程中,不断扩展回滚段,直到回滚段的最大范围数
或回滚段所在表空间空闲空间用完而出错。解决这个问题可以通过给删除数据的事务指定一个足够大的回滚段或者将回滚段所在表空间的AUTOEXTEND选项打开,同时将回滚段的MAXEXTENTS改大或设为UNLIMITED。不过这样仍存在一个隐患,如果删除的数据量大,同时数据库工作于归档模式下时,有可能导致日志切换频繁,所有日志文件都处于需要归档的状况,而归档进程来不及归档日志文件的情况出现,这时数据库将被挂起,直到有可用的日志文件后才恢复正常。
所以这种方法也不理想。

3、通过PL/SQL循环分段删除。
第三种方法是专门针对上面第二种方法进行优化改进的。这种方法通过一段PL/SQL程序循环分段删除数据,逐步提交事务,达到缩小事务规模,安全删除数据的目的。
例如有一个数据表t_table,我们将对其中字段c_date满足小于2001年1月1日的记录进行删除,可以采用以下的PL/SQL程序。

1 DECLARE
2 V_TEMP NUMBER;
3 BEGIN
4 LOOP
5 BEGIN
6 SELECT 1 INTO V_TEMP FROM t_table WHERE c_date < to_date(2000/01/01,yyyy/mm/dd) AND rownum = 1;
7 DELETE FROM t_table WHERE c_date < to_date(2000/01/01,yyyy/mm/dd) AND rownum < 100;
8 COMMIT;
9 EXCEPTION
10 WHEN NO_DATA_FOUND THEN
11 EXIT;
12 END;
13 END LOOP;
14 END;

程序的第1和第2行声明了一个临时变量。第4到第13行定义了一个循环,在这个循环中第6行不断检查表中是否还有满足条件的记录,如果有,第7行程序便执行删除操作,每次删除100记录,同时提交事务。当表中已无满足条件的记录时,便引起NO_DATA_FOUND的异常,从而退出循环。通过分批删除,逐步提交,缩小了事务的规模,从而达到避免出现回滚段错误的目的。然而这种方法依然存在因日志切换频繁,而归档进程来不及归档日志文件而导致数据库挂起的可能性。下面的程序通过ORACLE所提供的dbms_lock包中的过程sleep,解决了这个问题,从而达到安全快速大量删除数据的目的。

1 DECLARE
2 V_LOGNUM NUMBER; -- 数据库中拥有的日志文件数
3 V_NEEDARC NUMBER; -- 需要归档的日志文件数
4 BEGIN
5 SELECT count(1) INTO V_LOGNUM FROM V$LOG;
6 LOOP
7 LOOP
8 SELECT count(1) INTO V_NEEDARC FROM V$ARCHIVE;
9 IF V_NEEDARC < V_LOGNUM - 1 THEN
10 EXIT;
11 ELSE
12 DBMS_LOCK.SLEEP(60);
13 END IF;
14 END LOOP;
15
16 DELETE FROM t_table WHERE c_date < to_date(2000/01/01,yyyy/mm/dd) AND rownum < 100;
17 IF SQL%ROWCOUNT = 0 THEN
18 EXIT;
19 END IF;
20 COMMIT;
21 END LOOP;
22 END;
程序中的第2和第3行声明了两个变量v_lognum和v_needarc来保存数据库中日志文件的数量和当前需要归档的日志文件数量。
第5行获取了数据库中日志文件的数量。
第6行到第21行开始了删除数据的循环,第7行到第14行是一个子循环,不断检测当前需要归档的日志文件的数量v_needarc是否小于数据库的日志文件总数v_lognum减去1,如果满足条件,则退出子循环,开始删除数据。否则的话便调用dbms_lock.sleep()过程,使程序休眠60秒,然后继续子循环,检测需归档的日志文件数量。
第17到19行,检查删除数据的结果,如果已无数据,则退出,程序结束。
这个程序,通过利用dbms_output.sleep()过程,在删除过程中当需要归档的日志文件达到认定的限制时,使删除过程暂时停止,等待ARCH进程将日志文件归档后再继续进行,从而达到避免归档日志文件来不及归档,导致数据库挂起的问题。
此方法适用于oracle的各个版本。

4、使用NOLOGGING选项重新建表。
在ORACLE 8以后的版本中,CREATE TABLE命令提供了NOLOGGING的选项,在建表时不用写日志文件。
这样当我们在删除大量的数据时可以将要保留的数据通过CREATE TABLE ... NOLOGGING ... AS SELECT * FROM...的方法将要保留的数据备份到另一个表中,将原来的表删除,然后再 ALTER TABLE RENAME TO 命令将备份的表改为原来表的名字。
这个方法由于不写日志文件,所以速度很快,但是原来的表所拥有的索引和约束都将不存在,需重新建立。另外这个方法只适用于ORACLE 8以后的版本,ORACLE7.3中也可采用这个方法,但NOLOGGIN关键字要由UNRECOVERABLE代替。

前面比较了在ORACLE中如何批量删除数据的几种方法,以上这几种方法均在oracle 8i for windows,oracle 7.3 for windows,oracle 7.1 for netware中测试通过,在应用中可以根据实际情况选择一种合适的方法进行处理。

关于Oracle中大批量删除数据的方法,也可以参考Oracle专家eygle的文章:http://www.eygle.com/archives/2005/04/oracleoeouaeeae.html

如何在Oracle中批量删除数据相关推荐

  1. Oracle中批量删除数据

    在一个ORACLE数据库运行过程中,有时候会遇到要批量删除数据的情况,如一个保存历史数据的表中有大量的数据已经不需要保留,要将这部分数据删除.以下就这种情况可以采取的方法进行讨论.   1.使用TRU ...

  2. sql中批量删除数据

    dao层: xml 注意:发现根据id批量删除数据的时候不设置index属性也是可以的 当批量插入的时候那个时候是一个对象那个时候旧需要设置index属性了

  3. Oracle中大批量删除数据的方法

    批量删除海量数据通常都是很复杂及缓慢的,方法也很多,但是通常的概念是:分批删除,逐次提交. 下面是我的删除过程,我的数据表可以通过主键删除,测试过Delete和For all两种方法,for all在 ...

  4. oracle删除表中数据_工作表中提供的特定数据在数据库中批量删除的方法

    大家好,我们今日继续讲解VBA数据库解决方案的第25讲内容:利用VBA,把工作表中提供的数据在数据表中批量删除的方法.在上一讲中,我们讲了实现在数据表中删除记录的一般方法,这种方法可以对重复的数据进行 ...

  5. oracle procedures批量删除带索引条件数据很慢_见微知著,数据库应用设计优化浅谈...

    作者简介 刘晨 中航信研发中心 运维经理 前言:众所周知对于 OLTP 的交易系统最重要的操作就是数据库的CRUD,数据库层面或者SQL优化的程度,对于整个系统的并发处理能力起到至关重要的作用. 很多 ...

  6. oracle使用游标批量删除数据,oracle 游标批量处理数据

    declare --开始时间 v_date_start date:= to_date('2015-05-28 00:00:00','yyyy-mm-dd hh24:mi:ss'); --结束时间 v_ ...

  7. mysql批量删除数据库_数据库实现批量删除数据的操作方法(代码实例)

    本篇文章就给大家介绍数据库实现批量删除数据的操作方法.有一定的参考价值,有需要的朋友可以参考一下,希望对你们有所帮助.package com.mescs.baseinfo.utils; import ...

  8. linux 下删除批量文件命令,linux系统中批量删除文件与空文件删除的命令

    linux命令在系统中有两种类型:内置Shell命令和Linux命令.接下来是小编为大家收集的linux系统中批量删除文件与空文件删除的命令,希望能帮到大家. linux系统中批量删除文件与空文件删除 ...

  9. think php批量删除代码,ThinkPHP实现批量删除数据的代码实例

    ThinkPHP实现批量删除数据的代码实例 ThinkPHP实现批量删除数据原理很简单,只需在模板页面里面写上这样传过来就是一个数组,action的删除函数del()如下: /** **删除函数支持删 ...

最新文章

  1. 使用带有用户名和密码的cURL?
  2. C++的内存管理是怎样的
  3. Pandas与openpyxl库的 完美 融合!
  4. C++ vector容器删除操作
  5. 销售自动记帐凭证 - 三个常见问题
  6. SpringBoot_日志-日志框架分类和选择
  7. Python基础——zip、lambda、map
  8. l455在线清零服务器,爱普生epson l455清零软件官方版
  9. ssm房屋租赁管理系统ssm房屋管理系统JSP网上租房系统JSP房产信息网站房屋租赁系统房屋
  10. 无符号整型转点分十进制
  11. QQ农场外挂、QQ牧场外挂专偷QQ号
  12. 中国出口印度尼西亚主要商品
  13. 分词算法--正向最大匹配和逆向最大匹配实现
  14. 鸿蒙os系统测评,鸿蒙OS 2首批评价出炉,看已升级用户都怎么说的
  15. 【理论知识学习32】归纳偏差与选择性偏差(概念作用以及举例说明)
  16. mysql报错3009_MySQL修改密码方法汇总
  17. 7-75 正方体表面积计算
  18. JS基础-尚硅谷-滚动条-视频P110
  19. 销售清单怎么打印有什么软件
  20. 宝塔面板 SSL 证书安装部署

热门文章

  1. python 的高级特性:函数式编程,lambda表达式,装饰器
  2. ssh 连接kali_Kali NetHunter 零基础教程开启SSH连接 juiceSSH客户端
  3. STC89C52RC最小系统板原理图(12MHZ)
  4. 上海一日游记(r10笔记第87天)
  5. C语言字符界面,输入一串字符时可以随时按Esc键退出的工具函数
  6. git 保存当前修改, 切换分支, git 新建分支并提交到远程
  7. 奇怪的打印机java
  8. saltstack--grains
  9. C语言中空格符,制表符,换行符详解
  10. java list namevaluepair_NameValuePair方式传参数