游標
游標
概念
提供了一種對具有多行數據查詢結果集中的每一行數據分別進行單獨處理的方法
顯式游標
不帶參數的顯式游標
聲明一個游標,讀取學生的學號。
declare
cursor my_cursor is
select xh from xs;
v_xh xs.xh%type;
begin
open my_cursor;
fetch my_cursor into v_xh;
dbms_output.put_line('學號:'||v_xh);
dbms_output.put_line(my_cursor%rowcount);
close my_cursor;
exception
when others then
dbms_output.put_line(sqlcode||sqlerrm);
end;
學號:061101
1
帶參數的顯式游標
declare
varid number;
varname varchar2(50);
cursor mycur(v_xb xs.xb%type) is
select xh,xm from xs
where xb=v_xb;
begin
open mycur('男');
fetch mycur into varid,varname;
dbms_output.put_line('學生編號:'||varid||'學生姓名:'||varname);
close mycur;
end;
學生編號:61101學生姓名:王林
游標的屬性
declare
cursor c_1 is select * from xs;
v_1 c_1%rowtype;
begin
open c_1;
fetch c_1 into v_1;
dbms_output.put_line('學號:'||v_1.xh||'姓名:'||v_1.xm||'總學分:'||v_1.zxf);
fetch c_1 into v_1;
dbms_output.put_line('當前游標指向第'||c_1%rowcount||'行');
close c_1;
end;
學號:061101姓名:王林總學分:50
當前游標指向第2行
游標遍歷
使用游標分別遍歷xs表中的xh,zxf
declare
v_xh varchar2(6);
v_zxf number(2);
cursor xs_cur3 is select xh,zxf from xs;
begin
open xs_cur3;
fetch xs_cur3 into v_xh,v_zxf;
while xs_cur3%found
loop
dbms_output.put_line('學號:'||v_xh||'總學分'||v_zxf);
fetch xs_cur3 into v_xh,v_zxf;
end loop;
close xs_cur3;
end;
學號:061101總學分50
學號:101112總學分36
學號:001總學分45
學號:121112總學分36
學號:007總學分36
學號:007總學分55
利用游標WHILE循環統計並輸出scott.emp表各個部門的平均工資;若平均工資大於2000,則輸出「該部門平均工資較高”
declare
cursor c_dept_stat is select deptno,avg(sal) avgsal
from scott.emp group by deptno;
v_dept c_dept_stat%rowtype;
begin
open c_dept_stat;
fetch c_dept_stat into v_dept;
while c_dept_stat%found
loop
dbms_output.put_line('部門號:'||v_dept.deptno||'--'||'平均工資:'||trunc(v_dept.avgsal,1));
if(v_dept.avgsal >= 2000) then
dbms_output.put_line(v_dept.deptno||'號部門工資較高');
end if;
fetch c_dept_stat into v_dept;
end loop;
end;
部門號:30--平均工資:1566.6
部門號:20--平均工資:2175
20號部門工資較高
部門號:10--平均工資:2916.6
10號部門工資較高
利用FOR循環統計並輸出各個部門的平均工資
declare
cursor c_1 is select deptno,avg(sal) avgsal from scott.emp group by deptno;
v_dept c_1%rowtype;
begin
for v_dept in c_1
loop
dbms_output.put_line('部門號:'||v_dept.deptno||'--'||'平均工資:'||v_dept.avgsal);
end loop;
end;
部門號:30--平均工資:1566.666666666666666666666666666666666667
部門號:20--平均工資:2175
部門號:10--平均工資:2916.666666666666666666666666666666666667
帶update 的游標
Scott.emp表,利用游標,給工資低於1200 的員工增加工資50。並輸出「編碼為』員工編碼號』的工資已經更新」。
declare
v_empno scott.emp.empno%type;
v_sal scott.emp.sal%type;
cursor c_cursor is select empno,sal from scott.emp where sal <1200 for update;
begin
open c_cursor;
loop
fetch c_cursor into v_empno,v_sal;
exit when c_cursor%notfound;
update scott.emp set sal=sal+50 where current of c_cursor;-- 前面sal<1200
dbms_output.put_line('編碼為'||v_empno||'工資已更新!!');
DBMS_output.put_line('記錄數:'||c_cursor%rowcount);
end loop;
close c_cursor;
end;
編碼為7369工資已更新!!
記錄數:1
編碼為7876工資已更新!!
記錄數:2
編碼為7900工資已更新!!
記錄數:3
修改scott.emp表員工的工資,如果員工的部門號為10,工資提高100;部門號為20,工資提高150;部門號為30,工資提高200;否則工資提高250。
declare
cursor c_emp is select * from scott.emp for update;
v_zl number;
v_emp c_emp%rowtype;
begin
for v_emp in c_emp loop
case v_emp.deptno
when 10 then v_zl:=100;
when 20 then v_zl:=150;
when 30 then v_zl:=200;
else v_zl:=250;
end case;
update scott.emp set sal= sal+v_zl where current of c_emp;
end loop;
end;