今天在学习 REF CURSOR 游标时,百度了一下,发现很多人发了如下的一些学习类容。感觉讲的还不错,但是所举的例子可能因为作者一时大意写得有点问题(我自己做了标注) 。下面黑体字是转载的,会用红字标识出例子中的错误处!
Oracle
系列:
REF Cursor
在上文
Oracle
系列:
Cursor
(参见:
http://blog.csdn.net/qfs_v/archive/2008/05/06/2404794.aspx
)中
提到个思考:怎样让游标作为参数传递?
解决这个问题就需要用到
REF Cursor
。
1
,什么是
REF
游标
?
动态关联结果集的临时对象。即在运行的时候动态决定执行查询。
2
,
REF
游标
有什么作用?
实现在程序间传递结果集的功能,利用
REF CURSOR
也可以实现
BULK SQL
,从而提高
SQL
性能。
3
,静态游标和
REF
游标的区别是什么?
①
静态游标是静态定义,
REF
游标是动态关联;
②
使用
REF
游标需
REF
游标变量。
③
REF
游标能做为参数进行传递,而静态游标是不可能的。
4
,什么是
REF
游标变量?
REF
游标变量是一种
引用
REF
游标类型
的变量,指向动态关联的结果集。
5
,怎么使用
REF
游标
?
①
声明
REF
游标类型,确定
REF
游标类型;
⑴
强类型
REF
游标:指定
retrun type
,
REF
游标变量的类型必须和
return type
一致。
语法:
Type REF
游标名
IS Ref Cursor Return
结果集返回记录类型;
⑵
弱类型
REF
游标:不指定
return type
,能和任何类型的
CURSOR
变量匹配,用于获取任何结果集。
语法:
Type REF
游标名
IS Ref Cursor
;
②
声明
Ref
游标类型变量;
语法:变量名
已声明
Ref
游标类型;
③
打开
REF
游标,关联结果集
;
语法:
Open Ref
游标类型变量
For
查询语句返回结果集;
④
获取记录,操作记录;
语法:
Fatch REF
游标名
InTo
临时记录类型变量或属性类型变量列表;
⑤
关闭游标,完全释放资源;
语法:
Close REF
游标名;
例子:强类型
REF
游标
Declare
Type MyRefCurA IS REF CURSOR RETURN emp%RowType;
Type MyRefCurB IS REF CURSOR RETURN emp.ename%Type; --首先此处的返回类型不能这样写,“emp.ename%Type”表示的是数据类型,但是REF游标中此处的返回类型应该是记录类型。此处有两个修改方案。第一种把他改成弱类型REF;第二种是自己定义一个记录类型;
vRefCurA MyRefCurA;
vRefCurB MyRefCurB;
vTempA vRefCurA%RowType;
vTempB vRefCurB.ename%Type; --此处定义变量的类型也有错误。如果再上面已经把MyRefCurB改为弱类型,弱类型即不规定“不规定返回类型”(这样的用法肯定是不行的);我试了一下就算是强类型也无法实现。此处我建议,不要用游标变量来规定变量的类型;可以直接定义vTempA emp%rowtype;vTempB emp.ename%type;
Begin
Open vRefCurA For Select * from emp Where SAL > 2000;
Loop
Fatch vRefCurA InTo vTempA;
Exit When vRefCurA%NotFound;
DBMS_OUTPUT.PUT_LINE(vRefCurA%RowCount||' '|| vTempA.eno||' '||vTempA.ename ||' '||vTempA.sal) --缺少分号
End Loop;
Close vRefCurA;
DBMS_OUTPUT.PUT_LINE('-------------------------------------------------------------------------------------------------------');
Open vRefCurB For Select ename from emp Where SAL > 2000;
Loop
Fatch vRefCurB InTo vTempB;
Exit When vRefCurB%NotFound;
DBMS_OUTPUT.PUT_LINE(vRefCurB%RowCount||' '||vTempB) --此处缺少分号
End Loop;
Close vRefCurB;
DBMS_OUTPUT.PUT_LINE('-------------------------------------------------------------------------------------------------------');
Open vRefCurA For Select * from emp Where JOB = 'CLERK';
Loop
Fatch vRefCurA InTo vTempA;
Exit When vRefCurA%NotFound;
DBMS_OUTPUT.PUT_LINE(vRefCurA%RowCount||' '|| vTempA.eno||' '||vTempA.ename ||' '||vTempA.sal) --缺少分号
End Loop;
Close vRefCurA;
End;
例子:弱类型
REF
游标
/*conn scott/tiger*/
Declare
Type MyRefCur IS Ref Cursor;
vRefCur MyRefCur;
vtemp vRefCur%RowType;
Begin
Case(&n)
When 1 Then Open vRefCur For Select * from emp;
When 2 Then Open vRefCur For Select * from dept;
Else
Open vRefCur For Select eno, ename from emp Where JOB = 'CLERK';
End Case;
Close vRefCur;
End;
6
,怎样让
REF
游标作为参数传递?
我把上面的例子改了一下,可以运行了。
Declare
Type MyRefCurA IS REF CURSOR RETURN emp%RowType;
Type MyRefCurB IS REF CURSOR;
vRefCurA MyRefCurA;
vRefCurB MyRefCurB;
vTempA vRefCurA%RowType;
vTempB emp.ename%type;
Begin
Open vRefCurA For Select * from emp Where SAL > 2000;
Loop
Fetch vRefCurA InTo vTempA;
Exit When vRefCurA%NotFound;
DBMS_OUTPUT.PUT_LINE(vRefCurA%RowCount||' '|| vTempA.empno||' '||vTempA.ename ||' '||vTempA.sal);
End Loop;
Close vRefCurA;
DBMS_OUTPUT.PUT_LINE('-------------------------------------------------------------------------------------------------------');
Open vRefCurB For Select ename from emp Where SAL > 2000;
Loop
Fetch vRefCurB InTo vTempB;
Exit When vRefCurB%NotFound;
DBMS_OUTPUT.PUT_LINE(vRefCurB%RowCount||' '||vTempB);
End Loop;
Close vRefCurB;
DBMS_OUTPUT.PUT_LINE('-------------------------------------------------------------------------------------------------------');
Open vRefCurA For Select * from emp Where JOB = 'CLERK';
Loop
Fetch vRefCurA InTo vTempA;
Exit When vRefCurA%NotFound;
DBMS_OUTPUT.PUT_LINE(vRefCurA%RowCount||' '|| vTempA.empno||' '||vTempA.ename ||' '||vTempA.sal);
End Loop;
Close vRefCurA;
End;
本文出自 “技术” 博客,请务必保留此出处http://589985.blog.51cto.com/1609992/1054297