17.temp=rs.getObject(j+1);
18.}
19.}
20.}finally{
21.if(!
rs==null){
22.rs.close();
23.}
24.if(!
stmt==null){
25.stmt.close();
26.}
27.if(!
conn==null){
28.conn.close();
29.}
30.}
31.}
PL/SQL中对REF_CURSOR的调用
viewplainprint?
1.createorreplaceproceduretest_callis
2.c_cursorREFCURSOR_PKG.STRONG_REF_CURSOR;
3.r_empc_emp%rowtype;
4.begin
5.test(10,c_cursor);
6.loop
7.fetchc_cursorintor_emp;
8.exitwhenc_cursor%notfound;
9.dbms_output.put_line(r_emp.name);
10.endloop;
11.closec_cursor;
12.endtest_call;
viewplaincopytoclipboardprint?
1.createorreplaceproceduretest_callis
2.c_cursorREFCURSOR_PKG.STRONG_REF_CURSOR;
3.r_empc_emp%rowtype;
4.begin
5.test(10,c_cursor);
6.loop
7.fetchc_cursorintor_emp;
8.exitwhenc_cursor%notfound;
9.dbms_output.put_line(r_emp.name);
10.endloop;
11.closec_cursor;
12.endtest_call;
1,什么是REF游标?
动态关联结果集的临时对象。
即在运行的时候动态决定执行查询。
2,REF游标有什么作用?
实现在程序间传递结果集的功能,利用REFCURSOR也可以实现BULKSQL,从而提高SQL性能。
3,静态游标和REF游标的区别是什么?
①静态游标是静态定义,REF游标是动态关联;
②使用REF游标需REF游标变量。
③REF游标能做为参数进行传递,而静态游标是不可能的。
4,什么是REF游标变量?
REF游标变量是一种引用REF游标类型的变量,指向动态关联的结果集。
5,怎么使用REF游标?
①声明REF游标类型,确定REF游标类型;
⑴强类型REF游标:
指定retruntype,REF游标变量的类型必须和returntype一致。
语法:
TypeREF游标名ISRefCursorReturn结果集返回记录类型;
⑵弱类型REF游标:
不指定returntype,能和任何类型的CURSOR变量匹配,用于获取任何结果集。
语法:
TypeREF游标名ISRefCursor;
②声明Ref游标类型变量;
语法:
变量名已声明Ref游标类型;
③打开REF游标,关联结果集;
语法:
OpenRef游标类型变量For查询语句返回结果集;
④获取记录,操作记录;
语法:
FatchREF游标名InTo临时记录类型变量或属性类型变量列表;
⑤关闭游标,完全释放资源;
语法:
CloseREF游标名;
例子:
强类型REF游标
Declare
TypeMyRefCurAISREFCURSORRETURNemp%RowType;
TypeMyRefCurBISREFCURSORRETURNemp.ename%Type;
vRefCurAMyRefCurA;
vRefCurBMyRefCurB;
vTempAvRefCurA%RowType;
vTempBvRefCurB.ename%Type;
Begin
OpenvRefCurAForSelect*fromempWhereSAL>2000;
Loop
FatchvRefCurAInTovTempA;
ExitWhenvRefCurA%NotFound;
DBMS_OUTPUT.PUT_LINE(vRefCurA%RowCount||''||vTempA.eno||''||vTempA.ename||''||vTempA.sal)
EndLoop;
ClosevRefCurA;
DBMS_OUTPUT.PUT_LINE('-------------------------------------------------------------------------------------------------------');
OpenvRefCurBForSelectenamefromempWhereSAL>2000;
Loop
FatchvRefCurBInTovTempB;
ExitWhenvRefCurB%NotFound;
DBMS_OUTPUT.PUT_LINE(vRefCurB%RowCount||''||vTempB)
EndLoop;
ClosevRefCurB;
DBMS_OUTPUT.PUT_LINE('-------------------------------------------------------------------------------------------------------');
OpenvRefCurAForSelect*fromempWhereJOB='CLERK';
Loop
FatchvRefCurAInTovTempA;
ExitWhenvRefCurA%NotFound;
DBMS_OUTPUT.PUT_LINE(vRefCurA%RowCount||''||vTempA.eno||''||vTempA.ename||''||vTempA.sal)
EndLoop;
ClosevRefCurA;
End;
例子:
弱类型REF游标
Declare
TypeMyRefCurISRefCursor;
vRefCurMyRefCur;
vtempvRefCur%RowType;
Begin
Case(&n)
When1ThenOpenvRefCurForSelect*fromemp;
When2ThenOpenvRefCurForSelect*fromdept;
Else
OpenvRefCurForSelecteno,enamefromempWhereJOB='CLERK';
EndCase;
ClosevRefCur;
End;
6,怎样让REF游标作为参数传递?
这个是经过修改的,可以运行的程序:
Declare
TypeMyRefCurAISREFCURSOR;
vRefCurAMyRefCurA;
vRefCurBMyRefCurA;
vTempAemp%RowType;
vTempBemp.ename%Type;
Begin
OpenvRefCurAForSelect*fromempWhereSAL>2000;
Loop
FetchvRefCurAInTovTempA;
ExitWhenvRefCurA%NotFound;
DBMS_OUTPUT.PUT_LINE(vRefCurA%RowCount||''||vTempA.empno||''||vTempA.ename||''||vTempA.sal);
EndLoop;
ClosevRefCurA;
DBMS_OUTPUT.PUT_LINE('--------------------------------------');
OpenvRefCurBForSelectenamefromempWhereSAL>2000;
Loop
FetchvRefCurBInTovTempB;
ExitWhenvRefCurB%NotFound;
DBMS_OUTPUT.PUT_LINE(vRefCurB%RowCount||''||vTempB);
EndLoop;
ClosevRefCurB;
DBMS_OUTPUT.PUT_LINE('---------------------------------------');
OpenvRefCurAForSelect*fromempWhereJOB='CLERK';
Loop
FetchvRefCurAInTovTempA;
ExitWhenvRefCurA%NotFound;
DBMS_OUTPUT.PUT_LINE(vRefCurA%RowCount||''||vTempA.empno||''||vTempA.ename||''||vTempA.sal);
EndLoop;
ClosevRefCurA;
End;
2.
1.要执行返回REFCURSOR的存储过程,必须在OracleParameterCollection中定义参数,包括Cursor的OracleType以及Output的Direction。
数据提供程序只支持作为输出参数绑定REFCURSOR。
示例:
REFCURSOR示例(使用OracleScott/Tiger架构中定义的表)
创建Oracle包和包正文
CREATEORREPLACEPACKAGECURSPKGAS
TYPET_CURSORISREFCURSOR;
PROCEDUREOPEN_ONE_CURSOR(N_EMPNOINNUMBER,
IO_CURSORINOUTT_CURSOR);
PROCEDUREOPEN_TWO_CURSORS(EMPCURSOROUTT_CURSOR,
DEPTCURSOROUTT_CURSOR);
ENDCURSPKG;
/
CREATEORREPLACEPACKAGEBODYCURSPKGAS
PROCEDUREOPEN_ONE_CURSOR(N_EMPNOINNUMBER,
IO_CURSORINOUTT_CURSOR)
IS
V_CURSORT_CURSOR;
BEGIN
IFN_EMPNO<>0
THEN
OPENV_CURSORFOR
SELECTEMP.EMPNO,EMP.ENAME,DEPT.DEPTNO,DEPT.DNAME
FROMEMP,DEPT
WHEREEMP.DEPTNO=DEPT.DEPTNO
ANDEMP.EMPNO=N_EMPNO;
ELSE
OPENV_CURSORFOR
SELECTEMP.EMPNO,EMP.ENAME,DEPT.DEPTNO,DEPT.DNAME
FROMEMP,DEPT
WHEREEMP.DEPTNO=DEPT.DEPTNO;
ENDIF;
IO_CURSOR:
=V_CURSOR;
ENDOPEN_ONE_CURSOR;
PROCEDUREOPEN_TWO_CURSORS(EMPCURSOROUTT_CURSOR,
DEPTCURSOROUTT_CURSOR)
IS
V_CURSOR1T_CURSOR;
V_CURSOR2T_CURSOR;
BEGIN
OPENV_CURSOR1FORSELECT*FROMEMP;
OPENV_CURSOR2FORSELECT*FROMDEPT;
EMPCURSOR:
=V_CURSOR1;
DEPTCURSOR:
=V_CURSOR2;
ENDOPEN_TWO_CURSORS;
ENDCURSPKG;
/
示例:
OracleDataReader中的REFCURSOR参数
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Web;
usingSystem.Web.UI;
usingSystem.Web.UI.WebControls;
usingSystem.Configuration;
usingSystem.Data;
using