 
 
 
 
 
 
 
 
 
 
 
Some additional advantages of cursor variables are
Starting with Oracle7 release 7.3, you can use cursor variables in applications that run entirely in a single server session. You can declare cursor variables in PL/SQL subprograms, open them, and use them as parameters for other PL/SQL subprograms.
CREATE OR REPLACE PACKAGE emp_data AS
  TYPE emp_val_cv_type IS REF CURSOR RETURN emp%ROWTYPE;
  PROCEDURE open_emp_cv (emp_cv      IN OUT emp_val_cv_type,
                         dept_number     IN INTEGER); 
  PROCEDURE fetch_emp_data (emp_cv       IN emp_val_cv_type,
                            emp_row     OUT emp%ROWTYPE);
END emp_data;
CREATE OR REPLACE PACKAGE BODY emp_data AS
  PROCEDURE open_emp_cv (emp_cv      IN OUT emp_val_cv_type,
                         dept_number     IN INTEGER) IS
  BEGIN
    OPEN emp_cv FOR SELECT * FROM emp WHERE deptno = dept_number;
  END open_emp_cv;
  PROCEDURE fetch_emp_data (emp_cv       IN emp_val_cv_type,
                            emp_row     OUT emp%ROWTYPE) IS
  BEGIN
    FETCH emp_cv INTO emp_row;
  END fetch_emp_data;
END emp_data;
The following example shows how you can call the EMP_DATA package procedures from a PL/SQL block:
DECLARE
-- declare a cursor variable
  emp_curs emp_data.emp_val_cv_type;
  dept_number dept.deptno%TYPE;
  emp_row emp%ROWTYPE;
BEGIN
  dept_number := 20;
-- open the cursor using a variable
  emp_data.open_emp_cv(emp_curs, dept_number);
-- fetch the data and display it
  LOOP
    emp_data.fetch_emp_data(emp_curs, emp_row);
    EXIT WHEN emp_curs%NOTFOUND;
    DBMS_OUTPUT.PUT(emp_row.ename || '  ');
    DBMS_OUTPUT.PUT_LINE(emp_row.sal);
  END LOOP;
END;
CREATE OR REPLACE PACKAGE emp_dept_data AS
  TYPE cv_type IS REF CURSOR;
  PROCEDURE open_cv (cv          IN OUT cv_type,
                     discrim     IN     POSITIVE); 
END emp_dept_data;
/
CREATE OR REPLACE PACKAGE BODY emp_dept_data AS
  PROCEDURE open_cv (cv      IN OUT cv_type,
                     discrim IN     POSITIVE) IS
  BEGIN
    IF discrim = 1 THEN
      OPEN cv FOR SELECT * FROM emp WHERE sal > 2000;
    ELSIF discrim = 2 THEN
      OPEN cv FOR SELECT * FROM dept;
    END IF;
  END open_cv;
END emp_dept_data;You can call the OPEN_CV procedure to open the cursor variable and point it to either a query on the EMP table or on the DEPT table. How would you use this? The following PL/SQL block shows that you can fetch using the cursor variable, then use the ROWTYPE_MISMATCH predefined exception to handle either fetch:
DECLARE
  emp_rec  emp%ROWTYPE;
  dept_rec dept%ROWTYPE;
  cv       emp_dept_data.cv_type;
BEGIN
  emp_dept_data.open_cv(cv, 1); -- open CV for EMP fetch
  FETCH cv INTO dept_rec;       -- but fetch into DEPT record
                                -- which raises ROWTYPE_MISMATCH
  DBMS_OUTPUT.PUT(dept_rec.deptno);
  DBMS_OUTPUT.PUT_LINE('  ' || dept_rec.loc);
EXCEPTION
  WHEN ROWTYPE_MISMATCH THEN
    BEGIN
      DBMS_OUTPUT.PUT_LINE
           ('Row type mismatch, fetching EMP data...');
      FETCH cv into emp_rec;
      DBMS_OUTPUT.PUT(emp_rec.deptno);
      DBMS_OUTPUT.PUT_LINE('  ' || emp_rec.ename);
    END;
END;
 
 
 
 
 
 
 
 
