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游標
/*conn scott/tiger*/
Declare
Type MyRefCurA IS REF CURSOR RETURN emp%RowType;
Type MyRefCurB IS REF CURSOR RETURN emp.ename%Type;
vRefCurA MyRefCurA;
vRefCurB MyRefCurB;
vTempA vRefCurA%RowType;
vTempB vRefCurB.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游標作為參數傳遞?
--作為函數返回值
create or replace function returnacursor return sys_refcursor
is
v_csr sys_refcursor;
begin
open v_csr for select a1 from test3;
return v_csr;
end;
/
declare
c sys_refcursor;
a1 char(2);
begin
c:=returnacursor;
loop
fetch c into a1;
exit when c%notfound;
dbms_output.put_line(a1);
end loop;
close c;
end;
/
--作為參數
create or replace procedure proc_ref_cursor (rc in sys_refcursor) as
v_a number;
v_b varchar2(10);
begin
loop
fetch rc into v_a, v_b;
exit when rc%notfound;
dbms_output.put_line(v_a || ' ' || v_b);
end loop;
end;
/
declare
v_rc sys_refcursor;
begin
open v_rc for
select a1,a2 from test3;
proc_ref_cursor(v_rc);
close v_rc;
end;
/