您的位置:首页 > 数据库 > Oracle

Oracle 开发之 REF_CURSOR

2012-03-28 13:25 417 查看
《PL/SQL 语言开发参考手册》下载地址
前言
关于 REF_CURSOR 我们已经不再陌生,在前边的博客我们已经接触过了 REF_CURSOR:在博客《怎样让 Oracle 的存储过程返回结果集》中我们在一个返回结果集的 Hello World 级别的存储过程实例中用到了 REF_CURSOR,在博客《烟草局绩效考核系统打分模块开发笔记》中我们在一个真实的项目中体会到 REF_CURSOR 给我们带来的神奇效果。今天,我们将通过学习 Oracle 官方的这篇《Oracle 开发之 REF_CURSOR》进一步解开 REF_CURSOR 的神秘面纱,通过本文的学习,我们对 REF_CURSOR 的理解将会更加深入,而在以后的项目中对它的使用也必将更加规范。
正文
Oracle REF_CURSOR 简介
使用 REF_CURSOR 我们可以从存储过程中得到一个结果集对象。
REF_CURSOR 分为两种基本类型:强类型 REF_CURSOR 和弱类型 REF_CURSOR,强类型 REF_CURSOR 返回的数据类型和长度在编译期就应该指明,而弱类型 REF_CURSOR 不需要。
强类型 REF_CURSOR 和 Oracle 9i 之前的弱类型 REF_CURSOR 在包中应该这样定义:

[java] view plaincopyprint?

create or replace package REFCURSOR_PKG as

TYPE WEAK8i_REF_CURSOR IS REF CURSOR;

TYPE STRONG_REF_CURSOR IS REF CURSOR RETURN EMP%ROWTYPE;

end REFCURSOR_PKG;

[java] view plaincopyprint?

/** until Oracle 9 */

create or replace procedure test( p_deptno IN number

, p_cursor OUT

REFCURSOR_PKG.WEAK8i_REF_CURSOR)

is

begin

open p_cursor FOR

select *

from   emp

where  deptno = p_deptno;

end test;

/** until Oracle 9 */
create or replace procedure test( p_deptno IN number
, p_cursor OUT
REFCURSOR_PKG.WEAK8i_REF_CURSOR)
is
begin
open p_cursor FOR
select *
from   emp
where  deptno = p_deptno;
end test;

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

[java] view plaincopyprint?

/** From Oracle 9 */

create or replace procedure test( p_deptno IN number

, p_cursor OUT SYS_REFCURSOR)

is

begin

open p_cursor FOR

select *

from emp

where deptno = p_deptno;

end test;

/* Strong type */

create or replace procedure test( p_deptno IN number

, p_cursor OUT REFCURSOR_PKG.STRONG

REF_CURSOR)

is

begin

open p_cursor FOR

select *

from emp

where deptno = p_deptno;

end test;

[java] view plaincopyprint?

public void method() throws SQLException{

Connection conn = getConnection();

CallableStatement cstmt = null;

ResultSet rs = null;

int deptno = 10;

Object temp;

try{

cstmt = conn.prepareCall("begin  test(?,?); end;");

cstmt.setInt(1, deptno);

cstmt.registerOutParameter(2, OracleTypes.CURSOR);

cstmt.execute();

rs = (ResultSet) cstmt.getObject(2);

ResultSetMetaData rsm = rs.getMetaData();

int columnCount = rsm.getColumnCount();

while (rs.next()){

for (int j=0;j< columnCount;j++){

temp = rs.getObject(j+1);

}

}

} finally {

if (!rs==null){

rs.close();

}

if (!stmt==null){

stmt.close();

}

if (!conn==null){

conn.close();

}

}

}

public void method() throws SQLException{
Connection conn = getConnection();
CallableStatement cstmt = null;
ResultSet rs = null;
int deptno = 10;
Object temp;
try{
cstmt = conn.prepareCall("begin  test(?,?); end;");
cstmt.setInt(1, deptno);
cstmt.registerOutParameter(2, OracleTypes.CURSOR);
cstmt.execute();
rs = (ResultSet) cstmt.getObject(2);
ResultSetMetaData rsm = rs.getMetaData();
int columnCount = rsm.getColumnCount();
while (rs.next()){
for (int j=0;j< columnCount;j++){
temp = rs.getObject(j+1);
}
}
} finally {
if (!rs==null){
rs.close();
}
if (!stmt==null){
stmt.close();
}
if (!conn==null){
conn.close();
}
}
}

PL/SQL 中对 REF_CURSOR 的调用

[java] view plaincopyprint?

create or replace procedure test_call is

c_cursor REFCURSOR_PKG.STRONG_REF_CURSOR;

r_emp c_emp%rowtype;

begin

test(10,c_cursor);

loop

fetch c_cursor into r_emp;

exit when c_cursor%notfound;

dbms_output.put_line(r_emp.name);

end loop;

close c_cursor;

end test_call;

create or replace procedure test_call is
c_cursor REFCURSOR_PKG.STRONG_REF_CURSOR;
r_emp c_emp%rowtype;
begin
test(10,c_cursor);
loop
fetch c_cursor into r_emp;
exit when c_cursor%notfound;
dbms_output.put_line(r_emp.name);
end loop;
close c_cursor;
end test_call;
原文链接:http://www.oradev.com/ref_cursor.jsp
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: