cursor和绑定变量配合使用的标准模板

| No Comments

下个礼拜要给部门同事讲一下cursor和绑定变量的用法,我总结了cursor和绑定变量配合使用的4个标准模板,我这里把最有用的两个模板paste出来。

 

比如,现在我要把scott用户下的表emp中的sal字段都在其原先值的基础上加1,那么应用上述两个标准模板后写出来的存储过程就是下面的模样:

 

create or replace procedure p_demo_cursor_bind_template1 is

/*

用于演示当cursor所对应的数据量未知的情况下的标准处理方式,这里演示的是一条一条处理的方式

*/

 

  --定义批量fetch的数量,我这个例子里是10,建议值是1000

  CN_BATCH_SIZE constant pls_integer := 10;

 

  --定义存放fetch出来的结果集的数组,我这里例子里数组的大小是10,建议值是1000

  type typ_result is record(empno emp.empno%type,

                            ename emp.ename%type,

                            job emp.job%type,

                            mgr emp.mgr%type,

                            hiredate emp.hiredate%type,

                            sal emp.sal%type,

                            comm emp.comm%type,

                            deptno emp.deptno%type,

                            rid urowid);

  type typ_results is varray(10) of typ_result;

  results typ_results;

 

  --定义cursor,这里有三种定义方式

  --第一种方式,显式cursor

  /*cursor cur_emp

    is select empno,ename,job,mgr,hiredate,sal,comm,deptno,rowid from emp where empno>7000 order by empno;

  cursor cur_emp(n_empno_input number)

    is select empno,ename,job,mgr,hiredate,sal,comm,deptno,rowid from emp where empno>n_empno_input order by empno;*/

 

  --第二种方式,不带绑定变量的ref cursor

  /*cur_emp sys_refcursor;*/

 

  --第三种方式,带绑定变量的ref cursor,相当于带参数的显式cursor

  cur_emp sys_refcursor;

  vc_sql varchar2(200) := 'select empno,ename,job,mgr,hiredate,sal,comm,deptno,rowid from emp where empno>:1 order by empno';

 

begin

 

  --同样的,对应上述三种cursor有三种不同的打开方式

  --显式cursor的打开方式

  /*open cur_emp;

  open cur_emp(7000);*/

 

  --不带绑定变量的ref cursor的打开方式

  /*open cur_emp for select empno,ename,job,mgr,hiredate,sal,comm,deptno,rowid from emp where empno>7000 order by empno;*/

 

  --带绑定变量的ref cursor的打开方式

  open cur_emp for vc_sql using 7000;

 

  --第一种处理方式,一条一条处理

  loop

    fetch cur_emp bulk collect into results limit CN_BATCH_SIZE;

    for i in 1..results.count loop

   

      execute immediate 'update emp set sal=sal+1 where rowid = :1' using results(i).rid;

   

    end loop;

    exit when results.count < CN_BATCH_SIZE;

  end loop;

  close cur_emp;

 

  commit; 

 

end p_demo_cursor_bind_template1;

/

 

 

create or replace procedure p_demo_cursor_bind_template2 is

/*

用于演示当cursor所对应的数据量未知的情况下的标准处理方式,这里演示的是批量处理的方式

*/

 

  --定义批量fetch的数量,我这个例子里是10,建议值是1000

  CN_BATCH_SIZE constant pls_integer := 10;

 

  --定义存放fetch出来的结果集的数组

  type typ_empno is table of emp.empno%type index by binary_integer;

  empnos typ_empno;

  type typ_ename is table of emp.ename%type index by binary_integer;

  enames typ_ename;

  type typ_job is table of emp.job%type index by binary_integer;

  jobs typ_job;

  type typ_mgr is table of emp.mgr%type index by binary_integer;

  mgrs typ_mgr;

  type typ_hiredate is table of emp.hiredate%type index by binary_integer;

  hiredates typ_hiredate;

  type typ_sal is table of emp.sal%type index by binary_integer;

  sals typ_sal;

  type typ_comm is table of emp.comm%type index by binary_integer;

  comms typ_comm;

  type typ_deptno is table of emp.deptno%type index by binary_integer;

  deptnos typ_deptno;

  type typ_rid is table of urowid index by binary_integer;

  rids typ_rid;

 

  --定义cursor,这里有三种定义方式

  --第一种方式,显式cursor

  /*cursor cur_emp

    is select empno,ename,job,mgr,hiredate,sal,comm,deptno,rowid from emp where empno>7000 order by empno;

  cursor cur_emp(n_empno_input number)

    is select empno,ename,job,mgr,hiredate,sal,comm,deptno,rowid from emp where empno>n_empno_input order by empno;*/

 

  --第二种方式,不带绑定变量的ref cursor

  /*cur_emp sys_refcursor;*/

 

  --第三种方式,带绑定变量的ref cursor,相当于带参数的显式cursor

  cur_emp sys_refcursor;

  vc_sql varchar2(200) := 'select empno,ename,job,mgr,hiredate,sal,comm,deptno,rowid from emp where empno>:1 order by empno';

 

begin

 

  --同样的,对应上述三种cursor有三种不同的打开方式

  --显式cursor的打开方式

  /*open cur_emp;

  open cur_emp(7000);*/

 

  --不带绑定变量的ref cursor的打开方式

  /*open cur_emp for select empno,ename,job,mgr,hiredate,sal,comm,deptno,rowid from emp where empno>7000 order by empno;*/

 

  --带绑定变量的ref cursor的打开方式

  open cur_emp for vc_sql using 7000;

 

  --第二种处理方式,批量处理

  loop

    fetch cur_emp bulk collect into empnos,enames,jobs,mgrs,hiredates,sals,comms,deptnos,rids limit CN_BATCH_SIZE;

    for i in 1..rids.count loop    

      sals(i) := sals(i) + 1;

    end loop;

   

    forall i in 1..rids.count

      execute immediate 'update emp set sal=:1 where rowid = :2' using sals(i),rids(i);

     

    exit when rids.count < CN_BATCH_SIZE;

  end loop;

  close cur_emp;

 

  commit; 

 

end p_demo_cursor_bind_template2;

/

 

有兴趣的朋友可以看一下我上述两个存储过程里的注释。

Leave a comment