Oracle分批提交DML

Oracle分批提交DML 



1.采用分批操作并不能提高执行速度,执行效率不如单条DML语句。

2.分批插入可以减少对undo空间的占用,但频繁的提交,可能会导致前面提交的undo空间被其他事务占用而可能导致ORA-0155错误。

3.若分批操作中间半截失败掉,会将你数据库置于一种未知的状态。(DELETE操作不会出现这种情况)

   
1、分批UPDATE
DROP TABLE T2;
CREATE TABLE T2 AS SELECT OBJECT_NAME FROM DBA_OBJECTS;
SELECT * FROM T2; 
SELECT COUNT(*) FROM T2;
DECLARE
    TYPE RIDARRAY IS TABLE OF ROWID;
    TYPE VCARRAY IS TABLE OF T2.OBJECT_NAME%TYPE;
    L_RIDS  RIDARRAY;
    L_NAMES VCARRAY;
    CURSOR C IS
        SELECT ROWID,
               OBJECT_NAME
        FROM   T2;
BEGIN
    OPEN C;
    LOOP
        FETCH C BULK COLLECT
            INTO L_RIDS,
                 L_NAMES LIMIT 10;
        FORALL I IN 1 .. L_RIDS.COUNT
            UPDATE T2
            SET    OBJECT_NAME = LOWER(L_NAMES(I))
            WHERE  ROWID = L_RIDS(I);
        COMMIT;
        EXIT WHEN C%NOTFOUND;
    END LOOP;
    CLOSE C;
END;
/
2、分批DELETE
DROP TABLE T3; 
CREATE TABLE T3 AS SELECT * FROM DBA_OBJECTS; 
DECLARE
    CURSOR MYCURSOR IS
        SELECT ROWID FROM T3 ORDER BY ROWID; --按ROWID排序的CURSOR,删除条件是XXX=XXXX,根据实际情况修改 
    TYPE ROWID_TABLE_TYPE IS TABLE OF ROWID INDEX BY PLS_INTEGER;
    V_ROWID ROWID_TABLE_TYPE;
BEGIN
    OPEN MYCURSOR;
    LOOP
        FETCH MYCURSOR BULK COLLECT
            INTO V_ROWID LIMIT 5000; --每次处理5000行,也就是每5000行一提交 
        EXIT WHEN V_ROWID.COUNT = 0;
        FORALL I IN V_ROWID.FIRST .. V_ROWID.LAST
            DELETE FROM T3 WHERE ROWID = V_ROWID(I);
        COMMIT;
    END LOOP;
    CLOSE MYCURSOR;
END;
/
3、分批INSERT
将T_20160401的数据全部插入T_20160401_01表。
DECLARE
  CURSOR MYCURSOR IS
    SELECT ROWID FROM T_20160401 ORDER BY ROWID;
  TYPE ROWID_TABLE_TYPE IS TABLE OF  ROWID INDEX BY PLS_INTEGER ;
  V_ROWID ROWID_TABLE_TYPE;

  V_COUNT NUMBER := 0;
  V_START DATE;
  V_END   DATE;
BEGIN
  SELECT SYSDATE INTO V_START FROM DUAL;
  OPEN MYCURSOR;
  LOOP
    FETCH MYCURSOR BULK COLLECT
      INTO V_ROWID LIMIT 50000;
    EXIT WHEN V_ROWID.COUNT = 0;
   
FORALL I IN V_ROWID.FIRST .. V_ROWID.LAST
      INSERT INTO T_20160401_01
SELECT * FROM T_20160401 T WHERE T.ROWID=V_ROWID(I);
V_COUNT:=V_COUNT+TO_CHAR(SQL%ROWCOUNT);
    COMMIT;
  END LOOP;
  CLOSE MYCURSOR;
SELECT SYSDATE INTO V_END FROM DUAL;
  DBMS_OUTPUT.PUT_LINE('START: ' || V_START);
  DBMS_OUTPUT.PUT_LINE('INSERT: ' || V_COUNT);
  DBMS_OUTPUT.PUT_LINE('END: ' || V_END);
  COMMIT;
END;
/

DECLARE
  CURSOR MYCURSOR IS
    SELECT * FROM T_20160401 ORDER BY ROWID;
  TYPE ROWID_TABLE_TYPE IS TABLE OF T_20160401%ROWTYPE;
  V_ROWID ROWID_TABLE_TYPE;
BEGIN
  OPEN MYCURSOR;
  LOOP
    FETCH MYCURSOR BULK COLLECT
      INTO V_ROWID LIMIT 50000;
    EXIT WHEN V_ROWID.COUNT = 0;
  
    FORALL I IN V_ROWID.FIRST .. V_ROWID.LAST
      INSERT INTO T_20160401_01 VALUES V_ROWID(I);
    COMMIT;
  END LOOP;
  CLOSE MYCURSOR;
END;
/



About Me


...............................................................................................................................

● 本文作者:小麦苗,只专注于数据库的技术,更注重技术的运用

● 本文在itpub(http://blog.itpub.net/26736162)、博客园(http://www.cnblogs.com/lhrbest)和个人微信公众号(xiaomaimiaolhr)上有同步更新

● 本文itpub地址:http://blog.itpub.net/26736162/abstract/1/

● 本文博客园地址:http://www.cnblogs.com/lhrbest

● 本文pdf版及小麦苗云盘地址:http://blog.itpub.net/26736162/viewspace-1624453/

● 数据库笔试面试题库及解答:http://blog.itpub.net/26736162/viewspace-2134706/

● QQ群:230161599     微信群:私聊

● 联系我请加QQ好友(646634621),注明添加缘由

● 于 2017-06-02 09:00 ~ 2017-06-30 22:00 在魔都完成

● 文章内容来源于小麦苗的学习笔记,部分整理自网络,若有侵权或不当之处还请谅解

● 版权所有,欢迎分享本文,转载请保留出处

...............................................................................................................................

拿起手机使用微信客户端扫描下边的左边图片来关注小麦苗的微信公众号:xiaomaimiaolhr,扫描右边的二维码加入小麦苗的QQ群,学习最实用的数据库技术。

时间: 2024-10-09 22:02:16

Oracle分批提交DML的相关文章

Oracle并行操作——并行DML操作

  对大部分的OLTP系统而言,并行DML(PDML)的应用场景不多.大多数的PDML操作集中在下面几个场景下:   ü        系统移植,从旧系统中导入原始数据和基础数据: ü        数据仓库系统Data Warehouse定期进行大批量原始数据导入和清洗: ü        借助一些专门的工具,如sql loader,进行数据海量导入:   本篇主要介绍并行DML操作的一些细节和注意方面.   1.环境准备   Oracle并行操作前提两个条件,其一是盈余的软硬件资源,其二是海

深入内核:Oracle数据提交与事务隔离的深度解析

崔华,网名 dbsnake Oracle ACE Director,ACOUG 核心专家 编辑手记:感谢崔华授权我们独家转载其精品文章,也欢迎大家向"Oracle"社区投稿. 大家都知道的一个常识是 - Oracle 里未 commit 的数据除了当前 session 之外,其他 session 是看不到的. 我这里演示了一个有趣的例子,在这个例子里我们可以看到,Oracle里未成功 commit 的数据我们也可能能看到. 我同时启4个 session.   先在 session 1里

ORACLE 自动提交问题_oracle

于是写测试程序...不行 下载最新的ODBC...还是不行 通过sql plus查询...咦?竟然也查不到... 于是,折腾...折腾... 几个小时后,问题找到,原来PL/SQL DEVELOPER 默认不是自动提交,当关掉sql window窗口后或手动commit方进行数据的提交,我靠,真隐晦... 更改选项,插入,查询,一切OK了,唉,宝贵的时间啊. tool-preferences  

小麦苗BLOG文章索引

小麦苗BLOG文章索引            自从2014年7月1号开始写blog到2015年5月5日,历时10个月的时间,大概写了90篇文章,这blog多了就乱了,今天抽空出来整理整理,方便大家也方便自己阅读,本文将一直更新,另外,最后我把所有的blog文章全列出来,可能会有用.    小麦苗的所有文章:itpub文章链接-小麦苗.zip     2015年06月03日更新一次,我写的blog数量:109 篇    2015年07月03日更新一次,我写的blog数量:126 篇    2016

Oracle数据操作和控制语言详解 (一)

oracle|控制|数据|详解 SQL语言共分为四大类:数据查询语言DQL,数据操纵语言DML, 数据定义语言DDL,数据控制语言DCL.其中用于定义数据的结构,比如 创建.修改或者删除数据库:DCL用于定义数据库用户的权限:在这篇文章中我将详细讲述这两种语言在Oracle中的使用方法. DML语言 DML是SQL的一个子集,主要用于修改数据,下表列出了ORACLE支持的DML语句. 语句 用途 INSERT 向表中添加行 UPDATE 更新存储在表中的数据 DELETE 删除行 SELECT

oracle触发器及数据库触发简介

触发器是许多关系数据库系统都提供的一项技术.在ORACLE系统里,触发器类似过程和函数,都有声明,执行和异常处理过程的PL/SQL块. 1 触发器类型 触发器在数据库里以独立的对象存储,它与存储过程和函数不同的是,存储过程与函数需要用户显示调用才执行,而触发器是由一个事件来启动运行.即触发器是当某个事件发生时自动地隐式运行.并且,触发器不能接收参数.所以运行触发器就叫触发或点火(firing).ORACLE事件指的是对数据库的表进行的INSERT.UPDATE及DELETE操作或对视图进行类似的

Oracle的Commit知识

Oracle还是比较常用的,于是我研究了一下Oracle COMMIT,在这里拿出来和大家分享一下,希望对大家有用.只有当SQL语句影响的所有行所在的最后一个块被读入DB BUFFER并且重做信息被写入REDO LOG BUFFER之后,用户才可以发出COMMIT,Oracle COMMIT触发LGRW,但并不强制立即DBWN来释放所有相应的DB BUFFER块上的锁,但在随后的一段时间内DBWN还在写这条语句涉及的数据块的情形,表头部的行锁,并不是在COMMIT一发出就马上释放,实际上要等到相

对Oracle Commit的研究

Oracle还是比较常用的,于是我研究了一下Oracle COMMIT,在这里拿出来和大家分享一下,希望对 大家有用.只有当SQL语句影响的所有行所在的最后一个块被读入DB BUFFER并且重做信息被写入REDO LOG BUFFER之后,用户才可以发出COMMIT,Oracle COMMIT触发LGRW,但并不强制立即DBWN来释放所有 相应的DB BUFFER块上的锁,但在随后的一段时间内DBWN还在写这条语句涉及的数据块的情形,表头部 的行锁,并不是在COMMIT一发出就马上释放,实际上要

关于 Oracle 的数据导入导出及 Sql Loader (sqlldr) 的用法

在 Oracle 数据库中,我们通常在不同数据库的表间记录进行复制或迁移时会用以下几种方法: 1. A 表的记录导出为一条条分号隔开的 insert 语句,然后执行插入到 B 表中2. 建立数据库间的 dblink,然后用 create table B as select * from A@dblink where ...,或 insert into B select * from A@dblink where ...3. exp A 表,再 imp 到 B 表,exp 时可加查询条件4. 程序