oracle 之关键词 bulk collect

通过bulk collect减少loop处理的开销


     type wkas_row is record(a number(12), b number(12));
     type tbl_wkas is table of wkas_row;
     v_wkas tbl_wkas;


begin
    select a,b bulk collect into v_wkas
    from tbl_t
    where t='aaaaaa'
exception when others then
   null;
end;


批量处理数据,用于数据量大的时候来提高性能。


采用bulk collect可以将查询结果一次性地加载到collections中。

而不是通过cursor一条一条地处理。

可以在select into,fetch into,returning into语句使用bulk collect。

注意在使用bulk collect时,所有的into变量都必须是collections.



举几个简单的例子:

--在select into语句中使用bulk collect

DECLARE
   TYPE sallist 
IS   TABLE   OF  emp.sal % TYPE;

   sals   sallist;
BEGIN
--  Limit the number of rows to 100.
    SELECT  sal
   
BULK  COLLECT  INTO  sals
     
FROM  emp
    
WHERE  ROWNUM  <=   100 ;
--  Retrieve 10% (approximately) of the rows in the table.
    SELECT  sal  BULK  COLLECT  INTO  sals  FROM  emp SAMPLE  10 ;
END ;
/

--在fetch into中使用bulk collect

DECLARE
   TYPE deptrectab 
IS   TABLE   OF  dept % ROWTYPE;

   dept_recs   deptrectab;

   
CURSOR  c1
   
IS
      
SELECT  deptno, dname, loc
        
FROM  dept
       
WHERE  deptno  >   10 ;
BEGIN
   
OPEN  c1;

   
FETCH  c1
   
BULK  COLLECT  INTO  dept_recs;
END ;
/

--在returning into中使用bulk collect

CREATE   TABLE  emp2  AS   SELECT   *   FROM  employees;

DECLARE
   TYPE numlist 
IS   TABLE   OF  employees.employee_id % TYPE;

   enums   numlist;

   TYPE namelist 
IS   TABLE   OF  employees.last_name % TYPE;

   names   namelist;
BEGIN
   
DELETE   FROM  emp2
         
WHERE  department_id  =   30
     RETURNING       employee_id, last_name
   
BULK  COLLECT  INTO  enums, names;

   DBMS_OUTPUT.put_line (
' Deleted  '   ||  SQL % ROWCOUNT   ||   '  rows: ' );

   
FOR  i  IN  enums.FIRST .. enums.LAST
   LOOP
      DBMS_OUTPUT.put_line (
' Employee # '   ||  enums (i)  ||   ' '   ||  names (i));
   
END  LOOP;
END ;
/

DROP   TABLE  emp2;

 

为了测试returning into 关键字:


 CREATE TABLE loginuser(username VARCHAR2(20),passwd VARCHAR2(20))
 
 create or replace Procedure p_test_pro1 AS
   begin
        for v_i in 0..10 loop
        insert into loginuser values('admin'||v_i,'123456');
        end loop;
   end;
       
 create or replace Procedure p_test_pro1 AS
 TYPE namelist IS TABLE OF loginuser.username%TYPE;
 TYPE passwdlist IS TABLE OF loginuser.passwd%TYPE;
 nlist namelist;
 plist passwdlist;
 
 begin
   DELETE FROM loginuser WHERE ROWNUM<4 --删除操作测试
   RETURNING username,passwd BULK COLLECT INTO
   nlist,plist;
   dbms_output.put_line(SQL%ROWCOUNT);
  
   FOR i IN nlist.first..nlist.last
     LOOP
        dbms_output.put_line(nlist(i)||'----'||plist(i)); 
     END LOOP;
 end;

 

CREATE OR REPLACE Procedure p_test_pro1 AS
 TYPE namelist IS TABLE OF loginuser.username%TYPE;
 TYPE passwdlist IS TABLE OF loginuser.passwd%TYPE;
 nlist namelist;
 plist passwdlist;

 begin
--   DELETE FROM loginuser WHERE ROWNUM<4
  UPDATE loginuser t SET t.passwd='123'  --修改操作测试
   RETURNING username,passwd BULK COLLECT INTO
   nlist,plist;
   dbms_output.put_line(SQL%ROWCOUNT);

   FOR i IN nlist.first..nlist.last
     LOOP
        dbms_output.put_line(nlist(i)||'----'||plist(i));
     END LOOP;
 end;

你可能感兴趣的:(oracle,sql)