2019-05-13
游標(biāo)(cursor)能夠根據(jù)查詢條件從數(shù)據(jù)表中提取一組記錄,將其作為一個(gè)臨時(shí)表置于數(shù)據(jù)緩沖區(qū)中纺酸,利用指針逐行對(duì)記錄數(shù)據(jù)進(jìn)行操作。
隱式游標(biāo)
在執(zhí)行SQL語(yǔ)句時(shí),Oracle會(huì)自動(dòng)創(chuàng)建隱式游標(biāo)显熏,該游標(biāo)是內(nèi)存中處理該語(yǔ)句的數(shù)據(jù)緩沖區(qū),存儲(chǔ)了執(zhí)行SQL語(yǔ)句的結(jié)果晒屎。通過(guò)隱式游標(biāo)屬性可獲知SQL語(yǔ)句的執(zhí)行狀態(tài)信息喘蟆。
? %found:布爾型屬性缓升,如果sql語(yǔ)句至少影響到一行數(shù)據(jù),值為true蕴轨,否則為false港谊。
? %notfound:布爾型屬性,與%found相反尺棋。
? %rowcount:數(shù)字型屬性封锉,返回受sql影響的行數(shù)。
? %isopen:布爾型屬性膘螟,當(dāng)游標(biāo)已經(jīng)打開(kāi)時(shí)返回true成福,游標(biāo)關(guān)閉時(shí)則為false。
顯式游標(biāo)
用戶可以顯式定義游標(biāo)荆残。使用顯式游標(biāo)處理數(shù)據(jù)要4個(gè)步驟:定義游標(biāo)奴艾、打開(kāi)游標(biāo)、提取游標(biāo)數(shù)據(jù)和關(guān)閉游標(biāo)内斯。
1.定義游標(biāo)
游標(biāo)由游標(biāo)名稱和游標(biāo)對(duì)應(yīng)的select結(jié)果集組成蕴潦。定義游標(biāo)應(yīng)該放在pl/sql程序塊的聲明部分。
語(yǔ)法格式:cursor 游標(biāo)名稱(參數(shù)) is 查詢語(yǔ)句
2.打開(kāi)游標(biāo)
打開(kāi)游標(biāo)時(shí)俘闯,游標(biāo)會(huì)將符合條件的記錄送入數(shù)據(jù)緩沖區(qū)潭苞,并將指針指向第一條記錄。
語(yǔ)法格式:open 游標(biāo)名稱(參數(shù));
3.提取游標(biāo)數(shù)據(jù)
將游標(biāo)中的當(dāng)前行數(shù)據(jù)賦給指定的變量或記錄變量真朗。
語(yǔ)法格式:fetch 游標(biāo)名稱 into 變量名;
4.關(guān)閉游標(biāo)
游標(biāo)一旦使用完畢此疹,就應(yīng)將其關(guān)閉,釋放與游標(biāo)相關(guān)聯(lián)的資源遮婶。
語(yǔ)法格式:close 游標(biāo)名稱;
示例:編寫游標(biāo)蝗碎,統(tǒng)計(jì)雇員表中指定部門的工資在2000以下、2000-5000旗扑、以及5000以上的職工人數(shù)
declare
cursor emp_cursor( var_deptno in number) --定義游標(biāo)
is select * from scott.emp where deptno= var_deptno ;
var_emp scott.emp%rowtype;
var_deptno scott.emp.deptno%type;
num1 int default 0;
num2 int default 0;
num3 int default 0;
begin
var_deptno:=&var_deptno;
open emp_cursor(var_deptno); --打開(kāi)游標(biāo)
fetch emp_cursor into var_emp; --提取游標(biāo)數(shù)據(jù)
while emp_cursor%found loop --判斷是否有數(shù)據(jù)
if(var_emp.sal<2000) then
num1:=num1+1;
elsif(var_emp.sal<=5000) then
num2:=num2+1;
else
num3:=num3+1;
end if;
fetch emp_cursor into var_emp; --提取游標(biāo)數(shù)據(jù)
end loop;
close emp_cursor; --使用完游標(biāo)后必須顯式關(guān)閉
dbms_output.put_line('小于2000人數(shù):' || num1);
dbms_output.put_line('2000-5000人數(shù):' || num2);
dbms_output.put_line('大于5000人數(shù):' || num3);
end;
游標(biāo)FOR循環(huán)
PL/SQL提供了游標(biāo)for循環(huán)語(yǔ)句蹦骑,是遍歷顯式游標(biāo)的一種快捷方式。
特點(diǎn):
? 當(dāng)for循環(huán)開(kāi)始時(shí)臀防,游標(biāo)會(huì)自動(dòng)打開(kāi)(不需要使用open方法)眠菇。
? 每循環(huán)一次系統(tǒng)自動(dòng)讀取游標(biāo)當(dāng)前行的數(shù)據(jù)(不需要使用fetch)。
? 當(dāng)退出for循環(huán)時(shí)袱衷,游標(biāo)被自動(dòng)關(guān)閉(不需要使用close)琼锋。
for 變量 in 游標(biāo)名稱 loop
語(yǔ)句塊 ;
end loop ;
declare
cursor emp_cursor( var_deptno in number) --定義游標(biāo)
is select * from emp where deptno= var_deptno ;
var_deptno scott.emp.deptno%type;
num1 int default 0;
num2 int default 0;
num3 int default 0;
begin
var_deptno:=&var_deptno;
for var_emp in emp_cursor(var_deptno) loop
if(var_emp.sal<2000) then
num1:=num1+1;
elsif(var_emp.sal<=5000) then
num2:=num2+1;
else
num3:=num3+1;
end if;
end loop;
dbms_output.put_line('小于2000人數(shù):' || num1);
dbms_output.put_line('2000-5000人數(shù):' || num2);
dbms_output.put_line('大于5000人數(shù):' || num3);
end;
使用游標(biāo)更新記錄
cursor 游標(biāo)名稱 is 查詢語(yǔ)句 for update;
示例:更新雇員工資 規(guī)則:1000以內(nèi)增加300;2000以內(nèi)增加200;其它增加100。
declare
cursor emp_cursor is select * from scott.emp for update;
begin
for var_emp in emp_cursor loop
if var_emp.sal <= 1000 then
update scott.emp set sal = var_emp.sal+300
where current of emp_cursor;//游標(biāo)的當(dāng)前行
elsif var_emp.sal<=2000 then
update scott.emp set sal = var_emp.sal+200
where current of emp_cursor;
else
update scott.emp set sal = var_emp.sal+100
where current of emp_cursor;
end if;
end loop;
commit;
end;