Oracle 开发之 REFCURSOR.docx

上传人:b****1 文档编号:10484934 上传时间:2023-05-26 格式:DOCX 页数:16 大小:20.83KB
下载 相关 举报
Oracle 开发之 REFCURSOR.docx_第1页
第1页 / 共16页
Oracle 开发之 REFCURSOR.docx_第2页
第2页 / 共16页
Oracle 开发之 REFCURSOR.docx_第3页
第3页 / 共16页
Oracle 开发之 REFCURSOR.docx_第4页
第4页 / 共16页
Oracle 开发之 REFCURSOR.docx_第5页
第5页 / 共16页
Oracle 开发之 REFCURSOR.docx_第6页
第6页 / 共16页
Oracle 开发之 REFCURSOR.docx_第7页
第7页 / 共16页
Oracle 开发之 REFCURSOR.docx_第8页
第8页 / 共16页
Oracle 开发之 REFCURSOR.docx_第9页
第9页 / 共16页
Oracle 开发之 REFCURSOR.docx_第10页
第10页 / 共16页
Oracle 开发之 REFCURSOR.docx_第11页
第11页 / 共16页
Oracle 开发之 REFCURSOR.docx_第12页
第12页 / 共16页
Oracle 开发之 REFCURSOR.docx_第13页
第13页 / 共16页
Oracle 开发之 REFCURSOR.docx_第14页
第14页 / 共16页
Oracle 开发之 REFCURSOR.docx_第15页
第15页 / 共16页
Oracle 开发之 REFCURSOR.docx_第16页
第16页 / 共16页
亲,该文档总共16页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

Oracle 开发之 REFCURSOR.docx

《Oracle 开发之 REFCURSOR.docx》由会员分享,可在线阅读,更多相关《Oracle 开发之 REFCURSOR.docx(16页珍藏版)》请在冰点文库上搜索。

Oracle 开发之 REFCURSOR.docx

Oracle开发之REFCURSOR

前言

关于REF_CURSOR我们已经不再陌生,在前边的博客我们已经接触过了REF_CURSOR:

在博客《怎样让Oracle的存储过程返回结果集》中我们在一个返回结果集的HelloWorld级别的存储过程实例中用到了REF_CURSOR,在博客《烟草局绩效考核系统打分模块开发笔记》中我们在一个真实的项目中体会到REF_CURSOR给我们带来的神奇效果。

今天,我们将通过学习Oracle官方的这篇《Oracle开发之REF_CURSOR》进一步解开REF_CURSOR的神秘面纱,通过本文的学习,我们对REF_CURSOR的理解将会更加深入,而在以后的项目中对它的使用也必将更加规范。

正文

OracleREF_CURSOR简介

使用REF_CURSOR我们可以从存储过程中得到一个结果集对象。

REF_CURSOR分为两种基本类型:

强类型REF_CURSOR和弱类型REF_CURSOR,强类型REF_CURSOR返回的数据类型和长度在编译期就应该指明,而弱类型REF_CURSOR不需要。

强类型REF_CURSOR和Oracle9i之前的弱类型REF_CURSOR在包中应该这样定义:

viewplainprint?

1.createorreplacepackageREFCURSOR_PKGas

2.TYPEWEAK8i_REF_CURSORISREFCURSOR;

3.TYPESTRONG_REF_CURSORISREFCURSORRETURNEMP%ROWTYPE;

4.endREFCURSOR_PKG;

viewplaincopytoclipboardprint?

1.createorreplacepackageREFCURSOR_PKGas

2.TYPEWEAK8i_REF_CURSORISREFCURSOR;

3.TYPESTRONG_REF_CURSORISREFCURSORRETURNEMP%ROWTYPE;

4.endREFCURSOR_PKG;

返回REF_CURSOR的PL/SQL存储过程的编写示例:

viewplainprint?

1./**untilOracle9*/

2.createorreplaceproceduretest(p_deptnoINnumber

3.,p_cursorOUT

4.REFCURSOR_PKG.WEAK8i_REF_CURSOR)

5.is

6.begin

7.openp_cursorFOR

8.select*

9.fromemp

10.wheredeptno=p_deptno;

11.endtest;

viewplaincopytoclipboardprint?

1./**untilOracle9*/

2.createorreplaceproceduretest(p_deptnoINnumber

3.,p_cursorOUT

4.REFCURSOR_PKG.WEAK8i_REF_CURSOR)

5.is

6.begin

7.openp_cursorFOR

8.select*

9.fromemp

10.wheredeptno=p_deptno;

11.endtest;

Oracle9i之后,我们可以使用SYS_REFCURSOR作为REF_CURSOR的返回类型,例如:

viewplainprint?

1./**FromOracle9*/

2.createorreplaceproceduretest(p_deptnoINnumber

3.,p_cursorOUTSYS_REFCURSOR)

4.is

5.begin

6.openp_cursorFOR

7.select*

8.fromemp

9.wheredeptno=p_deptno;

10.endtest;

11.

12.

13./*Strongtype*/

14.

15.createorreplaceproceduretest(p_deptnoINnumber

16.,p_cursorOUTREFCURSOR_PKG.STRONG

17.REF_CURSOR)

18.is

19.begin

20.openp_cursorFOR

21.select*

22.fromemp

23.wheredeptno=p_deptno;

24.endtest;

viewplaincopytoclipboardprint?

1./**FromOracle9*/

2.createorreplaceproceduretest(p_deptnoINnumber

3.,p_cursorOUTSYS_REFCURSOR)

4.is

5.begin

6.openp_cursorFOR

7.select*

8.fromemp

9.wheredeptno=p_deptno;

10.endtest;

11.

12.

13./*Strongtype*/

14.

15.createorreplaceproceduretest(p_deptnoINnumber

16.,p_cursorOUTREFCURSOR_PKG.STRONG

17.REF_CURSOR)

18.is

19.begin

20.openp_cursorFOR

21.select*

22.fromemp

23.wheredeptno=p_deptno;

24.endtest;

JDBC对REF_CURSOR的调用

我们可以在JDBC中使用以下Java代码来得到REF_CURSOR:

viewplainprint?

1.publicvoidmethod()throwsSQLException{

2.Connectionconn=getConnection();

3.CallableStatementcstmt=null;

4.ResultSetrs=null;

5.intdeptno=10;

6.Objecttemp;

7.try{

8.cstmt=conn.prepareCall("begintest(?

?

);end;");

9.cstmt.setInt(1,deptno);

10.cstmt.registerOutParameter(2,OracleTypes.CURSOR);

11.cstmt.execute();

12.rs=(ResultSet)cstmt.getObject

(2);

13.ResultSetMetaDatarsm=rs.getMetaData();

14.intcolumnCount=rsm.getColumnCount();

15.while(rs.next()){

16.for(intj=0;j

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.}

viewplaincopytoclipboardprint?

1.publicvoidmethod()throwsSQLException{

2.Connectionconn=getConnection();

3.CallableStatementcstmt=null;

4.ResultSetrs=null;

5.intdeptno=10;

6.Objecttemp;

7.try{

8.cstmt=conn.prepareCall("begintest(?

?

);end;");

9.cstmt.setInt(1,deptno);

10.cstmt.registerOutParameter(2,OracleTypes.CURSOR);

11.cstmt.execute();

12.rs=(ResultSet)cstmt.getObject

(2);

13.ResultSetMetaDatarsm=rs.getMetaData();

14.intcolumnCount=rsm.getColumnCount();

15.while(rs.next()){

16.for(intj=0;j

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

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 经管营销

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2