cursor() 函數可以將一個查詢結果集封裝成一個類似 REF CURSOR 的游標變量
可以 FETCH 記錄
也可以作為 REF CURSOR 類型的參數進行傳遞
它被稱為
嵌套游標(nested cursor)
FETCH 記錄
我們先看一下測試表 test
和 test
的數據
SQL> select * from test
;
A
SQL> select * from test
;
ID NAME
yuechaotian
yuechaotian
yuechaotian
yuechaotian
yuechaotian
我們可能會發出這樣一個查詢
SQL> select id
name
(select a from test
where a = test
id)
from test
;
select id
name
(select a from test
where a = test
id)
*
ERROR 位於第
行:
ORA
: 單行子查詢返回多個行
因為表 test
中有兩條 a=
的記錄
所以這個查詢執行失敗了
但有時候我們確實需要這樣的查詢
怎麼辦呢?你可以試試 cursor() 函數
SQL> set serveroutput on
SQL> declare
cursor cur_test
is
select id
name
cursor(select a from test
where a = test
id)
from test
;
rec_test
test
%rowtype;
cur_test
sys_refcursor;
rec_test
test
%rowtype;
begin
open cur_test
;
loop
fetch cur_test
into rec_test
id
rec_test
name
cur_test
;
exit when cur_test
%notfound;
dbms_output
put_line(
rec_test
id:
|| rec_test
id ||
| rec_test
name:
|| rec_test
name);
這裡不需要再顯式 OPEN 游標 cur_test
也不需要顯式關閉
loop
fetch cur_test
into rec_test
;
exit when cur_test
%notfound;
dbms_output
put_line(
rec_test
a:
|| rec_test
a );
end loop;
end loop;
close cur_test
;
end;
/
rec_test
id:
| rec_test
name: yuechaotian
rec_test
a:
rec_test
a:
rec_test
id:
| rec_test
name: yuechaotian
rec_test
a:
rec_test
id:
| rec_test
name: yuechaotian
rec_test
a:
rec_test
id:
| rec_test
name: yuechaotian
rec_test
id:
| rec_test
name: yuechaotian
PL/SQL 過程已成功完成
怎麼樣?達到你的目的了吧
我們再看一個嵌套了兩個 cursor() 函數的例子
SQL> declare
嵌套定義游標
cursor cur_test
is
select id
name
cursor(select a
cursor(select * from dual)
from test
where test
a = test
id)
from test
;
cur_test
sys_refcursor;
cur_dual sys_refcursor;
rec_test
test
%rowtype;
rec_test
test
%rowtype;
rec_dual varchar
(
);
begin
open cur_test
;
loop
fetch cur_test
into rec_test
id
rec_test
name
cur_test
;
exit when cur_test
%notfound;
dbms_output
put_line(
rec_test
id:
|| rec_test
id ||
rec_test
name:
|| rec_test
name);
這裡不需要再顯式 OPEN 游標 cur_test
也不需要顯式關閉
loop
fetch cur_test
into rec_test
a
cur_dual;
exit when cur_test
%notfound;
dbms_output
put_line(
rec_test
a:
|| rec_test
a );
這裡不需要再顯式 OPEN 游標 cur_dual
也不需要顯式關閉
loop
fetch cur_dual into rec_dual;
exit when cur_dual%notfound;
dbms_output
put_line(
rec_dual:
|| rec_dual );
end loop;
end loop;
end loop;
close cur_test
;
end;
/
rec_test
id:
rec_test
name: yuechaotian
rec_test
a:
rec_dual: X
rec_test
a:
rec_dual: X
rec_test
id:
rec_test
name: yuechaotian
rec_test
a:
rec_dual: X
rec_test
id:
rec_test
name: yuechaotian
rec_test
a:
rec_dual: X
rec_test
id:
rec_test
name: yuechaotian
rec_test
id:
rec_test
name: yuechaotian
PL/SQL 過程已成功完成
由以上例子可以看出
嵌套游標是隱式打開的
它在以下情況下被關閉
顯式關閉
父游標再次執行時(比如
下一次循環前
會先關閉嵌套游標
再根據新數據重新打開)
父游標關閉時
父游標退出時
fetch 父游標出錯時
傳遞參數
我們先看看測試表中的數據
SQL> select * from test
;
ID NAME
yuechaotian
yuechaotian
yuechaotian
yuechaotian
yuechaotian
yuechaotian
yuechaotian
yuechaotian
yuechaotian
yuechaotian
已選擇
行
SQL> select * from test
order by a;
A
已選擇
行
下面我要查詢 test
中的數據
查詢條件是 test
id 在 test
a 中對應的記錄數
比如我要查詢表 test
id 在 test
a 中不存在的記錄
查詢表 test
id 在test
a 中存在
條的記錄
存在
條的記錄
存在
條的記錄……
我可以使用嵌套游標實現
SQL> create function f_count(cur_names in sys_refcursor) return number
is
v_name test
name%type;
n_count number(
) :=
;
begin
loop
fetch cur_names into v_name;
exit when cur_names%notfound;
n_count := n_count +
;
end loop;
return n_count;
end f_count;
/
函數已創建
SQL> select id
name
from test
where f_count( cursor( select a from test
where a = test
id ) ) =
;
ID NAME
yuechaotian
yuechaotian
yuechaotian
SQL> select id
name
from test
where f_count( cursor( select a from test
where a = test
id ) ) =
;
ID NAME
yuechaotian
yuechaotian
yuechaotian
yuechaotian
SQL> select id
name
from test
where f_count( cursor( select a from test
where a = test
id ) ) =
;
ID NAME
yuechaotian
yuechaotian
SQL> select id
name
from test
where f_count( cursor( select a from test
where a = test
id ) ) =
;
ID NAME
yuechaotian
From:http://tw.wingwit.com/Article/program/Oracle/201311/17957.html