游標用于處理查詢結果集中的數據
Oracle中提供了兩種游標類型,它們是:
靜態游標:靜態游標是在編譯時知道Select語句的游標。靜態游標又分為兩種類型,隱式游標和顯式游標。
REF游標:很多時候用戶需要為游標使用的查詢直到運行的時候才能確定,可以使用REF游標(引用游標)和游標變量滿足這個要求。為了使用引用游標,必須聲明游標變量。有兩種類型的REF游標,強類型REF游標和弱類型REF游標。
1、隱式游標:PL/SQL為所有SQL數據操縱語句(包括返回一行的Select)隱式聲明游標。用戶不能直接命名和控制此類游標。隱式游標名為SQL。
隱式游標屬性:
(1)、%FOUND只有在DML語句影響一行或多行時,%FOUND屬性才返回TRUE。
示例1:如果有行被更新,SQL%FOUND就返回真并打印相應信息。
begin
updateempsetsal=sal+8whereempno=7900;
ifsql%foundthen
dbms_output.put_line('表已更新');
else
dbms_output.put_line('編號未找到');
endif;
end;
(2)、%NOTFOUND此屬性與%FOUND屬性的作用正好相反。如果DML語句沒有影響任何行,則%NOTFOUND屬性返回TRUE。
(3)、%ROWCOUNT此屬性返回DML語句影響的行數。如果DML語句沒有影響任何行,則%ROWCOUNT屬性將返回0。
示例2:使用%ROWCOUNT屬性。
begin
updateempsetsal=sal+8whereempno=7900;
ifsql%foundthen
dbms_output.put_line('表已更新,更新了'||SQL%ROWCOUNT||'行');
else
dbms_output.put_line('編號未找到');
endif;
end;
(4)、%ISOPEN此屬性返回游標是否已打開的值。隱式游標的%ISOPEN屬性始終為FALSE。
2、顯式游標
使用顯式游標的4個步驟是:
(1)、聲明游標。
(2)、打開游標。
(3)、從游標中獲取記錄
(4)、關閉游標
聲明顯式游標語法:
CURSORcursor_name[(parameter[,parameter]...)]
[RETURNreturn_type]ISselect_statement;
其中:cursor_name指游標的名稱。
parameter用于為游標指定輸入參數。
return_type定義游標提取的行的類型。
select_statement指游標定義的查詢語句。
打開游標語法:
OPENcursor_name[(parameters)];
從游標中獲取記錄語法:
FETCHcursor_nameINTOvariables;
其中:cursor_name指游標的名稱。
variables是變量名。
關閉游標語法:
CLOSEcursor_name;
顯式游標的屬性如下:
(1)、%FOUND如果執行后一條FETCH語句成功返回行,則%FOUND的值為TRUE。
(2)、%NOTFOUND如果執行后一條FETCH語句未能提取行時,則%NOTFOUND的值為TRUE。
(3)、%ROWCOUNT返回到目前為止游標提取的行數。在第一次獲取之前,%ROWCOUNT為零。當FETCH語句返回一行時,則該數加1。
(4)、%ISOPEN如果游標已經打開,則返回TRUE,否則返回FALSE。
我們來一起看一個稍微復雜的例子
setserveroutputon
declare
cursorcur_deptisselect*fromdeptorderbydeptno;--定義游標
cursorcur_emp(mydeptnoinnumber)is
selectename,salfromempwheredeptno=mydeptno;
dept_recdept%rowtype;--聲明記錄類型變量
emp_recemp%rowtype;
mydeptnodept.deptno%type;
mydeptnamedept.dname%type;
myempnoemp.empno%type;
myenameemp.ename%type;
mysalemp.sal%type;
mytotalsalemp.sal%type;
begin
opencur_dept;--打開游標
loop
fetchcur_deptintodept_rec;--提取游標中的數據到記錄類型中
exitwhencur_dept%notfound;
dbms_output.put_line('departnois:'||dept_rec.deptno);
opencur_emp(dept_rec.deptno);
loop
fetchcur_empintomyename,mysal;
exitwhencur_emp%notfound;
dbms_output.put_line('employeenameis:'||myename);
dbms_output.put_line('salaryis:'||mysal);
--mytotalsal:=mytotalsal+mysal;
endloop;
closecur_emp;--關閉游標
--dbms_output.put_line('emploueesalaryis:'||mytotalsal);
endloop;
closecur_dept;
end;
三ref游標
REF游標和游標變量用于處理運行時動態執行的SQL查詢
創建游標變量需要兩個步驟:
聲明REF游標類型
聲明REF游標類型的變量
注意:不能賦予游標具體的sql語句
看一個例子
setserveroutputon
declare
typeemp_curisrefcursor;--聲明REF游標類型
emp_cur_objemp_cur;--聲明REF游標類型的變量
emp_recemp%rowtype;
dept_recdept%rowtype;
v_salemp.sal%type;
begin
v_sal:='&inputsal';
ifv_sal>3000then
openemp_cur_objforselect*fromemp;--給游標賦予動態的sql語句
loop
fetchemp_cur_objintoemp_rec;
exitwhenemp_cur_obj%notfound;
dbms_output.put_line('employeenameis'||emp_rec.ename);
endloop;
else
openemp_cur_objforselect*fromdept;--給游標賦予動態的sql語句
loop
fetchemp_cur_objintodept_rec;
exitwhenemp_cur_obj%notfound;
dbms_output.put_line('部門:'||dept_rec.dname);
endloop;
dbms_output.put_line('工資小于3000只查看部門信息');
endif;
closeemp_cur_obj;
end;