Oracle 游標


 


1、概念

    游標是指向SQL處理的內存區的句柄或指針。當使用一個PL/SQL塊來執行DML語句或只返回一行結果的SELECT語句時,系統將自動創建一個隱式游標。如果SQL語句返回多個結果,就必須創建一個顯示游標

--游標的屬性
--
(1)cur_name%rowcount :指出處理的行數
--
(2) cur_name%found :處理了一行或多行返回TRUE否則FALSE 如 WHILE CUR%FOUND中
--
(3)cur_name%notfound :如果沒有處理行返回TRUE,否則FALSE 如 EXIT WHEN CUR%NOTFOUND
--
(4)cur_name%isopen :如果處理之后不關閉游標,則為TRUE,關閉后為FALSE。發生在隱式游標中時
--
總是為FALSE;


 

2、隱式游標例程

 

1 declare
2 tname student.name%type;
3 tage student.age%type;
4 begin
5 select name,age into tname,tage from
6 student where id='S001';
7 --如果返回多行,或零行,執行將報錯。
8 dbms_output.put_line('姓名='||tname||' 年齡='||tage);
9 end;

3、顯示游標

3.1、定義游標

 

--  定義游標(1)     
--
CURSOR cursor_name IS select_statement;
cursor c_stu is select * from student;
---------------------------------------------------------------------------------------
     
-- 定義系統游標(2) ,使用參照3
--
cursor_name SYS_REFCURSOR;系統游標
c_stu sys_refcursor;
---------------------------------------------------------------------------------------


--定義游標(3)
--
先在包中定義游標,及用於檢索的結構體,
--
這里的結構體相當於 游標%rowtype
create or replace package p_stu
as
type c_stu is ref cursor;
type rc_stu is record
(
name student.name%type,
age student.age%type
);
end;

--使用包中的游標
declare
c_student p_stu.c_stu;
crw_stu p_stu.rc_stu;
begin
open c_student for select name,age from student;
loop
fetch c_student into crw_stu;
exit when c_student%notfound;
dbms_output.put_line('姓名='||crw_stu.name||' 年齡='||crw_stu.age);

end loop;
end;

3.2、一些使用游標的例子

--使用 FOR 循環遍歷游標,不需要明確打開和關閉游標


declare
--定義一個游標
cursor c_stu is
select name,age from student;
--定義一個游標變量
cw_stu c_stu%rowtype;
begin
for cw_stu in c_stu loop
dbms_output.put_line('姓名='||cw_stu.name||' 年齡='||cw_stu.age);
end loop;
end;

 

--使用 fetch 必須明確打開和關閉游標


declare
--定義一個游標
cursor c_stu is
select name,age from student;
--定義一個游標變量
cw_stu c_stu%rowtype;
begin
open c_stu; --明確打開游標
loop
fetch c_stu into cw_stu;
exit when c_stu%notfound;
dbms_output.put_line('姓名='||cw_stu.name||' 年齡='||cw_stu.age);
end loop;
close c_stu; --明確關閉游標
end;

 

--使用 while fetch 遍歷數據  %found屬性

declare
--定義一個游標
cursor c_stu is
select name,age from student;
--定義一個游標變量
cw_stu c_stu%rowtype;
begin
open c_stu; --明確打開游標
fetch c_stu into cw_stu; --填充第一行數據,以便WHILE條件檢索
while c_stu%found loop
dbms_output.put_line('姓名='||cw_stu.name||' 年齡='||cw_stu.age);
fetch c_stu into cw_stu; --每次檢索前都需要填充數據
end loop;
close c_stu; --明確關閉游標
end;

 3.3、在存儲過程中返回游標

--  注意:在declare塊中使用存儲過程返回的游標時:
--
(1)不能定義系統游標變量,編譯錯誤。如:cw_Stu C_Stu%rowtype;
--
(2)可以使用結構體變量,但不能使用for循環如:for rw_stu in c_stu loop
--
將提示 c_stu '不是過程或尚未定義'。
--
(3)游標不可顯示打開或關閉,如 open c_stu;表達式類型錯誤。


(1)返回系統游標

----  ***1、返回系統游標的過程 sys_cursor
create or replace procedure pro_SysCur(CId in varchar2,Cur_Stu out sys_refcursor)
as
begin
open Cur_Stu for select name,age from student where ClassId=CId;
end;


-- 使用
--
測試結果:
--
(1)不能定義系統游標變量,編譯錯誤。如:cw_Stu C_Stu%rowtype;
--
(2)可以使用結構體變量,但不能使用for循環如:for rw_stu in c_stu loop
--
將提示 c_stu '不是過程或尚未定義'。
--
(3)游標不可顯示打開或關閉,如 open c_stu;表達式類型錯誤。
declare
C_Stu Sys_RefCursor;
type rec_stu is record(
tname student.name%type,
tage student.age%type
);
rw_stu rec_stu;
begin
pro_syscur('C001',c_stu);
loop
--也可以寫成 fetch c_stu into rw_stu.tname,rw_stu.tage;
--或直接定義表字段類型變量
fetch c_stu into rw_stu;
exit when c_stu%notfound;
dbms_output.put_line('姓名='||rw_stu.tname||' 年齡='||rw_stu.tage);
end loop;
end;

(1)返回自定義游標

 

--第一步,在包中定義游標,及用於遍歷的結構體
create or replace package pack_stu
as
type c_pubsur is ref cursor;
type re_stu is record(
tname student.name%type,
tage student.age%type
);
num number;
end;
--第二步,將存儲過程的返回類型設為上面包中游標類型
create or replace procedure p_stu(cid in varchar2,c_s out pack_stu.c_pubsur)
as
begin
open c_s for select name,age from student where classid=cid;
end;
--第三步,使用游標,注意事項與系統游標一致。
declare
c_stu pack_stu.c_pubsur;
cw_stu pack_stu.re_stu;
begin
p_stu('C001',c_stu);
loop
fetch c_stu into cw_stu;
exit when c_stu%notfound;
dbms_output.put_line('姓名='||cw_stu.tname||' 年齡='||cw_stu.tage);
end loop;
end;










 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM