Oracle: Ref Cursors
Oracle: Ref Cursors
Oracle: Ref Cursors
REF CURSORS:
A PL/SQL PROGRAM CANNOT PASS A CURSOR AS A PARAMETER TO ANOTHER PROGRAM. A PL/SQL PROGRAM CAN ONLY OPEN THE CURSOR AND PROCESS THE CORRESPONDING INFORMATION WITHIN THE PROGRAM ITSELF. TO WORK AROUND THE FUNCTIONAL LIMITATIONS OF CURSORS A PROGRAM CAN INSTEAD DECLARE TWO DIFFERENT CURSOR TYPES AND CORRESPONDING CURSOR VARIABLES. CURSOR CAN BE DECLARED AS EITHER STRONG OR WEAK. THESE TYPES OF CURSOR DECLARATIONS ARE USED TO PASS A CURSOR AS A PARAMETER TO A PROGRAM OR A PACKAGE. WHETHER A CURSOR IS STRONG OR WEAK DEPENDS UPON THE WAY IT IS DECLARED. FOR EXAMPLE, THE CURSOR TYPE DECLARED BELOW IS A STRONG CURSOR TYPE I.E., THE CURSOR TYPES DECLARATION INCLUDES A RETURN CLAUSE THAT SPECIFIES A SHAPE OR SET OF ATTRIBUTES FOR THE CURSOR TYPE. A STRONG CURSOR TYPE CAN ONLY RETURN THE DATA TYPE SPECIFIED IN THE RETURN TYPE. THEREFORE, A STRONG CURSOR TYPE RESTRICTS THE DEFINITION OF SUBSEQUENT CURSOR VARIABLES THAT USE THE TYPE. TYPE CU R_EMP IS REF CURSOR RETURN EMP.EMPNO%TYPE EMP_CURSOR! CUR_EMP """""""""""""""" CURSOR VARIABLE. EMP_CURSOR# CUR_EMP """""""""""""""" CURSOR VARIABLE. EMP_CURSOR$ CUR_EMP """""""""""""""" CURSOR VARIABLE. THE FOLLOWING CURSOR TYPE IS WEAK BECAUSE IT DOES NOT INCLUDE A SHAPE SPECIFICATION %.&., THERE IS NO RETURN CLAUSE.' A PROGRAM CAN USE THE WEAK CURSOR TYPE TO DECLARE A CURSOR VARIABLE WITH AN Y SHAPE.
PL/SQL
ORACLE
A WEAK CURSOR TYPE CAN RETURN ANY DATATYPE AS THERE IS NO RETURN CLAUSE. SINCE THERE IS NO RETURN VALUE FOR THE CURSOR , THE CURSOR VARIABLE IS SHAPE INDEPENDENT. THIS ADDS FLEXIBILITY TO THE CURSOR VARIABLES. FOR EXAMPLE( TYPE CUR_EMP IS REF CURSOR SQL) CREATE OR REPLACE PACKAGE DEPT_DATA AS TYPE DEPTCURTYP IS REF CURSOR RETURN DEPT%ROWTYPE PROCEDURE OPEN_DEPT_CV *DEPT_CV IN OUT DEPTCURTYP+ END DEPT_DATA / P,-.,/& -0&,1&2. SQL) CREATE OR REPLACE PACKAGE BODY DEPT_DATA AS PROCEDURE OPEN_DEPT_CV *DEPT_CV IN OUT DEPTCURTYP+ IS BEGIN OPEN DEPT_CV FOR SELECT 3 FROM DEPT END OPEN_DEPT_CV END DEPT_DATA / P,-.,/& 4526 -0&,1&2. WHEN U DECLARE A CURSOR VARIABLE AS THE FORMAL PARAMETER OF A SUBPROGRAM THAT OPENS THE CURSOR VARIABLE. YOU MUST SPECIFY THE IN OUT MODE. THAT WAY, THE SUBPROGRAM CAN PASS AN OPEN CURSOR BACK TO THE CALLER. DECLARE A VARIABLE OF TYPE REFCURSOR AS SHOWN BELOW.
PL/SQL
ORACLE
SQL) EXECUTE DEPT_DATA.OPEN_DEPT_CV *( VARDEPTCV+ PL/SQL 705-&280& 98--&99:8;;6 -5<7;&1&2. SQL) PRINT VARDEPTNO SQL) PRINT VARDEPTCV DEPTNO DNAME """""""""" """""""""""""" """"""""""""" != ACCOUNTING #= RESEARCH $= SALES >= OPERATIONS LOC NEW YORK DALLAS CHICAGO BOSTON
EXECUTE THE PACKAGE WITH THE SPECIFIED PROCEDURE ALONG WITH THE CURSOR AS SHOWN BELOW(
ALTERNATIVELY, YOU CAN USE THE SET AUTOPRINT ON COMMAND BEFORE EXECUTING THE PACKAGE, TODISPLAY THE QUERY RESULTS AUTOMATICALLY. USE THE SET AUTOPRINT OFF COMMAND TO PUT AUTOPRINT OFF. THE PROCEDURE CAN BE EXECUTED MULTIPLE TIMES USING THE SAME OR A DIFFERENT REFCURSOR BIND VARIABLE AS SHOWN BELOW( SQL) VARIABLE PCV REFCURSOR SQL) SET AUTOPRINT ON SQL) EXECUTE DEPT_DATA.OPEN_DEPT_CV*(PCV+ PL/SQL 705-&280& 98--&99:8;;6 -5<7;&1&2. DEPTNO DNAME """""""""" """""""""""""" """"""""""""" != ACCOUNTING #= RESEARCH $= SALES >= OPERATIONS SQL) SET AUTOPRINT OFF LOC NEW YORK DALLAS CHICAGO BOSTON
PL/SQL
ORACLE
ALTERNATIVELY, YOU CAN USE A STANDALONE PROCEDURE TO OPEN THE CURSOR VARIABLE. SIMPLE DEFINE THE REFCURSOR TYPE IN A SEPARATE PACKAGE, THEN REFERENCE THAT TYPE IN THE STANDALONE PROCEDURE. FOR INSTANCE, IF YOU CREATE THE FOLLOWING *BODILESS+ PACKAGE, U CAN CREATE STANDALONE PROCEDURE THAT REFERENCES THE TYPES IT DEFINES( SQL) CREATE OR REPLACE PACKAGE CV_TYPES AS TYPE GENERICCURTYPE IS REFCURSOR TYPE EMPCURTYP IS REF CURSOR RETURN EMP%ROWTYPE TYPE DEPTCURTYP IS REF CURSOR RETURN DEPT%ROWTYPE END CV_TYPES / W,0?%?/( P,-.,/& -0&,1&2 @%1A -5<7%;,1%5? &00509. SQL) SHOW ERRORS E00509 :50 PACKAGE CV_TYPES( LINE/COL ERROR """""""" """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" #/#> PLS"==!=$( E?-58?1&0&2 1A& 96<45; BREFCURSORB @A&? &C7&-1%?/ 5?& 5: 1A& :5;;5@%?/( * ,00,6 ;%<%1&2 ?&@ 70%D,1& 0,?/& 0&-502 VARRAY_ -A,0_4,9& ?8<4&0_4,9& 2&-%<,; 2,1&_4,9& -;54_4,9& 4;54_4,9& 4:%;&_4,9& 1,4;& 0&: 54E&-1 :%C&2 D,06%?/ 57,F8& TA& 96<45; B0,?/&B @,9 98491%181&2 :50 BREFCURSORB 15 -5?1%?8&. CREATE OR REPLACE PACKAGE CV_TYPES AS TYPE GENERICCURTYPE IS REF CURSOR TYPE EMPCURTYP IS REF CURSOR RETURN EMP%ROWTYPE TYPE DEPTCURTYP IS REF CURSOR RETURN DEPT%ROWTYPE END CV_TYPES SQL) / P,-.,/& -0&,1&2.
PL/SQL
ORACLE
IN THE FOLLOWING EXAMPLE , YOU CREATE A STANDLONE PROCEDURE THAT REFERENCES THE REF CURSOR TYPE EMPCURTYP, WHICH IS DEFINED IN THE PACKAGE CV_TYPES( SQL) CREATE PROCEDURE OPEN_EMP_CV *EMP_CV IN OUT CV_TYPES.EMPCURTYP+ AS BEGIN OPEN EMP_CV FOR SELECT 3 FROM EMP END OPEN_EMP_CV / P05-&280& -0&,1&2. SQL) VARIABLE P REFCURSOR SQL) EXECUTE OPEN_EMP_CV*(P+ PL/SQL 705-&280& 98--&99:8;;6 -5<7;&1&2. SQL) PRINT P EMPNO ENAME GOB MGR HIREDATE SAL """""""""" """""""""" """"""""" """""""""" """"""""" """""""""" """""""""" """""""""" H$IJ SMITH CLERK HJ=# !H"DEC"K= K== H>JJ ALLEN SALESMAN HIJK #="FEB"K! !I== HL#! WARD SALESMAN HIJK ##"FEB"K! !#L= HLII GONES MANAGER HK$J =#"APR"K! #JHL HIL> MARTIN SALESMAN HIJK #K"SEP"K! !#L= HIJK BLAKE MANAGER HK$J =!"MAY"K! #KL= HHK# CLARK MANAGER HK$J =J"GUN"K! #>L= HHKK SCOTT ANALYST HLII !J"APR"KH $=== HK$J KING PRESIDENT !H"NOV"K! L=== HK>> TURNER SALESMAN HIJK =K"SEP"K! !L== HKHI ADAMS CLERK HHKK #$"MAY"KH !!== HJ== GAMES CLERK HIJK =$"DEC"K! JL= HJ=# FORD ANALYST HLII =$"DEC"K! $=== HJ$> MILLER CLERK HHK# #$"GAN"K# !$== !> 05@9 9&;&-1&2. COMM $== L== !>== DEPTNO #= $= $= #= $= $= != #= != $= #= $= #= !=
PL/SQL
ORACLE
SQL) CREATE OR REPLACE PACKAGE EMP_DATA AS # TYPE GENERICCURTYP IS REF CURSOR $ TYPE EMPCURTYP IS REF CURSOR RETURN EMP%ROWTYPE > PROCEDURE OPEN_EMP_CV*EMP_CV IN OUT EMPCURTYP, CHOICE IN NUMBER+ L END EMP_DATA I / P,-.,/& -0&,1&2. SQL) CREATE OR REPLACE PACKAGE BODY EMP_DATA AS # PROCEDURE OPEN_EMP_CV*EMP_CV IN OUT EMPCURTYP, CHOICE IN NUMBER+ $ IS > BEGIN L IF CHOICE M ! THEN I OPEN EMP_CV FOR H SELECT 3 FROM EMP WHERE COMM IS NOT NULL K ELSIF CHOICE M # THEN J OPEN EMP_CV FOR != SELECT 3 FROM EMP WHERE SAL ) #L== !! ELSIF CHOICE M $ THEN !# OPEN EMP_CV FOR !$ SELECT 3 FROM EMP WHERE DEPTNOM#= !> END IF !L END OPEN_EMP_CV !I END EMP_DATA !H / P,-.,/& 4526 -0&,1&2. SQL) VARIABLE EMPCUR REFCURSOR SQL) SET AUTOPRINT ON SQL) EXECUTE EMP_DATA.OPEN_EMP_CV*(EMPCUR,$+ PL/SQL 705-&280& 98--&99:8;;6 -5<7;&1&2.
PL/SQL
ORACLE
EMPNO ENAME GOB MGR HIREDATE SAL """""""""" """""""""" """"""""" """""""""" """"""""" """""""""" """""""""" """""""""" H$IJ SMITH CLERK HJ=# !H"DEC"K= K== HLII GONES MANAGER HK$J =#"APR"K! #JHL HHKK SCOTT ANALYST HLII !J"APR"KH $=== HKHI ADAMS CLERK HHKK #$"MAY"KH !!== HJ=# FORD ANALYST HLII =$"DEC"K! $=== SQL) EXECUTE EMP_DATA.OPEN_EMP_CV*(EMPCUR,#+ PL/SQL 705-&280& 98--&99:8;;6 -5<7;&1&2. EMPNO ENAME GOB MGR HIREDATE SAL COMM """""""""" """""""""" """"""""" """""""""" """"""""" """""""""" """""""""" """""""""" HLII GONES MANAGER HK$J =#"APR"K! #JHL HIJK BLAKE MANAGER HK$J =!"MAY"K! #KL= HHKK SCOTT ANALYST HLII !J"APR"KH $=== HK$J KING PRESIDENT !H"NOV"K! L=== HJ=# FORD ANALYST HLII =$"DEC"K! $=== SQL) EXECUTE EMP_DATA.OPEN_EMP_CV*(EMPCUR,!+ PL/SQL 705-&280& 98--&99:8;;6 -5<7;&1&2. EMPNO ENAME GOB MGR HIREDATE SAL """""""""" """""""""" """"""""" """""""""" """"""""" """""""""" """""""""" """""""""" H>JJ ALLEN SALESMAN HIJK #="FEB"K! !I== HL#! WARD SALESMAN HIJK ##"FEB"K! !#L= HIL> MARTIN SALESMAN HIJK #K"SEP"K! !#L= HK>> TURNER SALESMAN HIJK =K"SEP"K! !L== COMM $== L== !>== = DEPTNO $= $= $= $= DEPTNO #= $= #= != #= COMM DEPTNO #= #= #= #= #=
FOR MORE FLEXIBILITY , YOU CAN PASS A CURSOR VARIABLE AND SELECTOR TO A STORED PROCEDURE THAT EXECUTES QUERIES WITH DIFFERENT RETURN TYPES.
PL/SQL
ORACLE
SQL) CREATE OR REPLACE PACKAGE EMP_DATA AS # TYPE GENERICCURTYP IS REF CURSOR $ TYPE EMPCURTYP IS REF CURSOR RETURN EMP%ROWTYPE > PROCEDURE OPEN_CV*GENERIC_CV IN OUT GENERICCURTYP, CHOICE IN NUMBER+ L END EMP_DATA I / P,-.,/& -0&,1&2. SQL) CREATE OR REPLACE PACKAGE BODY EMP_DATA AS # PROCEDURE OPEN_CV*GENERIC_CV IN OUT GENERICCURTYP, CHOICE IN NUMBER+ $ IS > BEGIN L IF CHOICEM! THEN I OPEN GENERIC_CV FOR SELECT 3 FROM EMP H ELSIF CHOICE M # THEN K OPEN GENERIC_CV FOR SELECT 3 FROM DEPT J ELSIF CHOICEM$ THEN != OPEN GENERIC_CV FOR SELECT 3 FROM SALGRADE !! END IF !# END OPEN_CV !$ END EMP_DATA !> / P,-.,/& 4526 -0&,1&2. SQL) VARIABLE CUR REFCURSOR SQL) SET AUTOPRINT ON SQL) EXECUTE EMP_DATA.OPEN_CV*(CUR,$+ PL/SQL 705-&280& 98--&99:8;;6 -5<7;&1&2. GRADE LOSAL HISAL """""""""" """""""""" """""""""" ! H== !#== # !#=! !>== $ !>=! #=== > #==! $=== L $==! JJJJ
PL/SQL
ORACLE
SQL) EXECUTE EMP_DATA.OPEN_CV*(CUR,#+ PL/SQL 705-&280& 98--&99:8;;6 -5<7;&1&2. DEPTNO DNAME """""""""" """""""""""""" """"""""""""" != ACCOUNTING #= RESEARCH $= SALES >= OPERATIONS LOC NEW YORK DALLAS CHICAGO BOSTON
SQL) EXECUTE EMP_DATA.OPEN_CV*(CUR,!+ PL/SQL 705-&280& 98--&99:8;;6 -5<7;&1&2. EMPNO ENAME GOB MGR HIREDATE SAL """""""""" """""""""" """"""""" """""""""" """"""""" """""""""" """""""""" """""""""" H$IJ SMITH CLERK HJ=# !H"DEC"K= K== H>JJ ALLEN SALESMAN HIJK #="FEB"K! !I== HL#! WARD SALESMAN HIJK ##"FEB"K! !#L= HLII GONES MANAGER HK$J =#"APR"K! #JHL HIL> MARTIN SALESMAN HIJK #K"SEP"K! !#L= HIJK BLAKE MANAGER HK$J =!"MAY"K! #KL= HHK# CLARK MANAGER HK$J =J"GUN"K! #>L= HHKK SCOTT ANALYST HLII !J"APR"KH $=== HK$J KING PRESIDENT !H"NOV"K! L=== HK>> TURNER SALESMAN HIJK =K"SEP"K! !L== HKHI ADAMS CLERK HHKK #$"MAY"KH !!== HJ== GAMES CLERK HIJK =$"DEC"K! JL= HJ=# FORD ANALYST HLII =$"DEC"K! $=== HJ$> MILLER CLERK HHK# #$"GAN"K# !$== !> 05@9 9&;&-1&2. COMM $== L== !>== DEPTNO #= $= $= #= $= $= != #= != $= #= $= #= !=
PL/SQL