Sunday, December 07, 2008

Cursor Variables - Impementing Variant Records

The power of cursor variables comes from their ability to point to different cursors.
This test example comes from this doc



denis@TEST10G>
denis@TEST10G> create table emp_tab
2 as
3 select
4 rownum empno,
5 object_name ename,
6 mod(rownum, 10) + 1 deptno ,
7 rownum * 100 sal
8 from all_objects
9 where rownum < 100;

Table created.

denis@TEST10G>
denis@TEST10G>
denis@TEST10G> drop table dept_tab purge;

Table dropped.

denis@TEST10G> create table dept_tab
2 as
3 select
4 rownum deptno,
5 'd_' || rownum deptname
6 from all_objects
7 where rownum <=10;

Table created.

denis@TEST10G>
denis@TEST10G>
denis@TEST10G> -- In the following package example, a discriminant is used to
denis@TEST10G> -- open a cursor variable to point to one of two different cursors:
denis@TEST10G>
denis@TEST10G> create or replace package emp_dept_data as
2 type cv_type is ref cursor;
3 procedure open_cv(cv in out cv_type,
4 discrim in positive);
5 end emp_dept_data;
6 /

Package created.

denis@TEST10G>
denis@TEST10G> create or replace package body emp_dept_data as
2 procedure open_cv (cv in out cv_type,
3 discrim in positive) is
4 begin
5 if discrim = 1 then
6 open cv for select * from emp_tab where sal > 2000;
7 elsif discrim = 2 then
8 open cv for select * from dept_tab;
9 end if;
10 end open_cv;
11 end emp_dept_data;
12 /

Package body created.

denis@TEST10G>
denis@TEST10G> -- You can call the open_cv procedure to open the cursor variable
denis@TEST10G> -- and point it to either a query on the emp_tab table or
denis@TEST10G> -- the dept_tab table.
denis@TEST10G>
denis@TEST10G> declare
2 emp_rec emp_tab%rowtype;
3 dept_rec dept_tab%rowtype;
4 cv emp_dept_data.cv_type;
5
6 begin
7 -- emp_dept_data.open_cv(cv,2); -- open cv for emp_tab fetch
8 emp_dept_data.open_cv(cv,1); -- open cv for emp_tab fetch
9 fetch cv into dept_rec; -- but fetch inot dept_tab record
10 -- which raises rowtype_mismatch
11 dbms_output.put(dept_rec.deptno);
12 dbms_output.put_line(' ' || dept_rec.deptname);
13 exception
14 when rowtype_mismatch then
15 begin
16 dbms_output.put_line
17 ('Row type mismatch, fetching emp_tab data ...');
18 fetch cv into emp_rec;
19 dbms_output.put(emp_rec.deptno);
20 dbms_output.put_line(' ' || emp_rec.ename);
21 end;
22 end;
23 /
Row type mismatch, fetching emp_tab data ...
2 C_TS#

PL/SQL procedure successfully completed.


No comments: