游标
游标
概念
提供了一种对具有多行数据查询结果集中的每一行数据分别进行单独处理的方法
显式游标
不带参数的显式游标
声明一个游标,读取学生的学号。
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;