【DB笔试面试468】分批插入、分批更新、分批删除、分批提交的写法有哪些?

  • 2019 年 10 月 11 日
  • 筆記

题目部分

分批插入、分批更新、分批删除、分批提交的写法有哪些?

答案部分

这个知识点也是检测程序员编程能力的主要考题,分为3个类别:分批插入、分批更新、分批删除及分批提交。主要采用游标加BULK COLLECT的方式来实现,用LIMIT来限制每次需要操作的行数。其中,分批更新也可以采用游标FOR循环加ORDER BY排序的方式,效率也是非常不错的。

下面作者给出3个模版程序,若笔试中出现类似的题目,则可以照猫画虎。

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;  /

本文选自《Oracle程序员面试笔试宝典》,作者:李华荣。

About Me:小麦苗

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

● 作者博客地址:http://blog.itpub.net/26736162/abstract/1/

● 本系列题目来源于作者的学习笔记,部分整理自网络,若有侵权或不当之处还请谅解

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

● 题目解答若有不当之处,还望各位朋友批评指正,共同进步

Exit mobile version