如何在Pl / SQl中使用批量收集和插入

时间:2014-01-13 07:23:53

标签: sql plsql bulkinsert

我想从一个表中获取大约6百万行,并将它们全部插入到另一个表中。 如何使用BULK COLLECTFORALL

执行此操作

3 个答案:

答案 0 :(得分:9)

declare
  -- define array type of the new table
  TYPE new_table_array_type IS TABLE OF NEW_TABLE%ROWTYPE INDEX BY BINARY_INTEGER;

  -- define array object of new table
  new_table_array_object new_table_array_type;

  -- fetch size on  bulk operation, scale the value to tweak
  -- performance optimization over IO and memory usage
  fetch_size NUMBER := 5000;

  -- define select statment of old table
  -- select desiered columns of OLD_TABLE to be filled in NEW_TABLE
  CURSOR old_table_cursor IS
    select * from OLD_TABLE; 

BEGIN

  OPEN old_table_cursor;
  loop
    -- bulk fetch(read) operation
    FETCH old_table_cursor BULK COLLECT
      INTO new_table_array_object LIMIT fetch_size;
    EXIT WHEN old_table_cursor%NOTFOUND;

    -- do your business logic here (if any)
    -- FOR i IN 1 .. new_table_array_object.COUNT  LOOP
    --   new_table_array_object(i).some_column := 'HELLO PLSQL';    
    -- END LOOP;    

    -- bulk Insert operation
    FORALL i IN INDICES OF new_table_array_object SAVE EXCEPTIONS
      INSERT INTO NEW_TABLE VALUES new_table_array_object(i);
    COMMIT;

  END LOOP;
  CLOSE old_table_cursor;
End;

希望这有帮助。

答案 1 :(得分:1)

oracle

Below is an example From

CREATE OR REPLACE PROCEDURE fast_way IS

TYPE PartNum IS TABLE OF parent.part_num%TYPE
INDEX BY BINARY_INTEGER;
pnum_t PartNum;

TYPE PartName IS TABLE OF parent.part_name%TYPE
INDEX BY BINARY_INTEGER;
pnam_t PartName;

BEGIN
  SELECT part_num, part_name
  BULK COLLECT INTO pnum_t, pnam_t
  FROM parent;

  FOR i IN pnum_t.FIRST .. pnum_t.LAST
  LOOP
    pnum_t(i) := pnum_t(i) * 10;
  END LOOP;

  FORALL i IN pnum_t.FIRST .. pnum_t.LAST
  INSERT INTO child
  (part_num, part_name)
  VALUES
  (pnum_t(i), pnam_t(i));
  COMMIT;
END

答案 2 :(得分:0)

SQL引擎解析并执行SQL语句,但在某些情况下,会将数据返回到PL / SQL引擎。

在执行PL / SQL语句期间,每个SQL语句都会导致两个引擎之间的上下文切换。当PL / SQL引擎找到SQL语句时,它会停止并将控制权传递给SQL引擎。 SQL引擎执行该语句并返回到PL / SQL引擎中的数据。这种控制转移是调用Context Switch。通常在PL / SQL引擎之间切换非常快,但上下文切换执行大量时间损害性能。 SQL引擎检索所有行并将它们加载到集合中并切换回PL / SQL引擎。使用批量收集多行可以使用单个上下文切换来获取。

示例:1

DECLARE

Type stcode_Tab IS TABLE OF demo_bulk_collect.storycode%TYPE;
Type category_Tab IS TABLE OF demo_bulk_collect.category%TYPE;
s_code stcode_Tab;
cat_tab category_Tab;
Start_Time NUMBER;
End_Time NUMBER;

CURSOR c1 IS 
select storycode,category from DEMO_BULK_COLLECT;
BEGIN
   Start_Time:= DBMS_UTILITY.GET_TIME;
   FOR rec in c1
   LOOP
     NULL;
     --insert into bulk_collect_a values(rec.storycode,rec.category);
   END LOOP;
    End_Time:= DBMS_UTILITY.GET_TIME;
    DBMS_OUTPUT.PUT_LINE('Time for Standard Fetch  :-' ||(End_Time-Start_Time) ||'  Sec');

    Start_Time:= DBMS_UTILITY.GET_TIME;    
    Open c1;
        FETCH c1 BULK COLLECT INTO s_code,cat_tab;
    Close c1;
 FOR x in s_code.FIRST..s_code.LAST
 LOOP
 null;        
 END LOOP;
End_Time:= DBMS_UTILITY.GET_TIME; 
DBMS_OUTPUT.PUT_LINE('Using Bulk collect fetch time :-' ||(End_Time-Start_Time) ||'  Sec');
END;