Oracle bulk collect into 的幾種用法


bulk collect 和 forall 聯合應用寫起來顯得有些啰嗦,不過為了速度,多寫兩句又何妨

建立兩個臨時表

    create table T_TEST  
    (  
      TESTID      NUMBER(19) not null,  
      TESTNAME    VARCHAR2(512),  
      TESTTYPE    VARCHAR2(512),  
      TESTLEVEL   VARCHAR2(512),  
      ADDFLAG     VARCHAR2(512)  
    );  
    create table T_TEST2  
    (  
      TESTID      NUMBER(19) not null,  
      TESTNAME    VARCHAR2(512),  
      TESTTYPE    VARCHAR2(512),  
      TESTLEVEL   VARCHAR2(512),  
    );  


存儲過程使用示例1:

    create or replace procedure FAST_UP_TEST is  
    TYPE TARR is table of T_TEST%ROWTYPE;  
    vvrr TARR;  
    CURSOR curr is select * from T_TEST where ADDFLAG='add';  
    begin  
      open curr;  
      loop  
        fetch curr bulk collect into vvrr limit 1000;  
        dbms_output.put_line('增加:'||vvrr.count);  
        forall i in 1..vvrr.count  
          update T_TEST2  
          set TESTTYPE=vvrr(i).TESTTYPE,TESTLEVEL=vvrr(i).TESTLEVEL   
          where TESTNAME=vvrr(i).TESTNAME and TESTID=vvrr(i).TESTID;  
          commit;  
        exit when curr%NOTFOUND;  
      end loop;  
      close curr;  
    end;  

換一個方式使用示例(注意游標返回類型變化):

create or replace procedure FAST_DEL_TEST is  
TYPE TARR is table of T_TEST.TESTID%TYPE;  
vvrr TARR;  
CURSOR curr is select TESTID from T_TEST where ADDFLAG='delete';  
begin  
  dbms_output.enable(90000);  
  open curr;  
  loop  
    fetch curr bulk collect into vvrr limit 1000;  
    dbms_output.put_line('delete T_TEST '||vvrr.count);  
    forall i in 1..vvrr.count  
      delete T_TEST2  
      where TESTID=vvrr(i);  
      commit;  
    exit when curr%NOTFOUND;  
  end loop;  
  close curr;  
end; 

多參數返回的另一種用法和動態sql運行辦法

    create or replace procedure FAST_AD_TEST (  
      tabtest in VARCHAR2) is  
    TYPE TARR_ID is table of T_TEST.TESTID%TYPE;  
    TYPE TARR_NM is table of T_TEST.TESTNAME%TYPE;  
    TYPE TARR_TP is table of T_TEST.TESTTYPE%TYPE;  
    vvid TARR_ID;  
    vvnm TARR_NM;  
    vvtp TARR_TP;  
    CURSOR curr is select TESTID,TESTNAME,TESTTYPE from T_TEST where ADDFLAG='add';  
    CURSOR curd is select TESTID from T_TEST where ADDFLAG='delete';  
    begin  
      execute immediate 'truncate table '||tabtest;  
      -- forall只能寫一條sql。。。  
      open curr;  
      loop  
        fetch curr bulk collect into vvid,vvnm,vvtp limit 1000;  
        forall i in 1..vvid.count  
          insert into T_TEST2(TESTID,TESTNAME,TESTTYPE) values (vvid(i),vvnm(i),vvtp(i));  
          commit;  
        exit when curr%NOTFOUND;  
      end loop;  
      close curr;  
      -- 動態傳入表名和參數  
      open curd;  
      loop  
        fetch curd bulk collect into vvid limit 1000;  
        forall i in 1..vvid.count  
          execute immediate 'delete '||tabtest||' where TESTID=:tabid' using in vvid(i);  
          commit;  
        exit when curd%NOTFOUND;  
      end loop;  
      close curd;  
    end;  

bulk collect 和 forall 的聯合應用
基本上壓榨出了oracle中增刪改的極限速度。
比用游標一條條處理要快太多了。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM