1.游标的使用(cursor)
基本格式:
定义游标: cursor 游标名 is select语句(查询要操作的数据);
自定义参数:参数名1 对应表中的字段1;
参数名2 对应表中的字段2;
打开游标: open 游标名;
loop(循环)
fetch ... into ...; 抓取一行到自定义变量里面
exit when ...%notfound; 退出循环的条件
具体操作...
end loop; 关闭循环
关闭游标: close 游标名;
例:
1 declare 2 cursor cemp is select job,sal from emp; ###定义了一个名称是cemp的游标,游标中的数据是select job,sal from emp;中查询出的数据 3 cjob emp.job%type; ###定义变量cjob,对应emp表中的job字段 4 csal emp.sal%type; ###定义变量csal,对应emp表中的sal字段 5 begin 6 open cemp; ###打开游标 7 loop ###循环 8 fetch cemp into cjob,csal; ###抓取游标中的一行数据赋值给变量cjob,csal 9 exit when cemp%notfound; ###退出条件:cemp%notfound表示游标没有抓取到数据了 10 dbms_output.put_line('您的工作为' || cjob || '您的工资为' || csal); ###具体操作:打印工作、工资 11 end loop; ###结束循环 12 close cemp; ###关闭游标 13 end; 14 /
-- 游标的四个属性
1). %isopen 判断游标是否打开
2). %rowcount 影响的行
3). %found 还有下一条数据
4). %notfound 没有下一条数据
例: --根据emp表员工的职位涨工资,总裁涨1000,经理涨800,其他涨400。
1 declare 2 cursor cemp is select empno,job from emp; 3 pempno emp.empno%type; 4 pjob emp.job%type; 5 begin 6 open cemp; 7 loop 8 fetch cemp into pempno,pjob; 9 exit when cemp%notfound; 10 if pjob ='PRESIDENT' then update emp set sal = sal + 1000 where empno = pempno; 11 elsif pjob='MANAGER' then update emp set sal = sal + 800 where empno = pempno; 12 else 13 update emp set sal = sal + 400 where empno = pempno; 14 end if; 15 end loop; 16 close cemp; 17 end; 18 /
注意:elsif 的书写。
-- 带参数的游标
例: -- 要查询emp表任意部门的员工信息。(10号部门)
1 declare 2 cursor cemp(pdeptno number) is select empno,ename from emp where deptno = pdeptno; 3 pempno emp.empno%type; 4 pname emp.ename%type; 5 begin 6 open cemp(10); 7 loop 8 fetch cemp into pempno,pname; 9 exit when cemp%notfound; 10 dbms_output.put_line(pempno || ' ' || pname ); 11 end loop; 12 close cemp; 13 end; 14 /
2.例外(exception)
例:
1 declare 2 pnum number := 0; 3 begin 4 pnum := 1/pnum; -- 会抛出一个叫zero_divide的异常 5* end; 6 / declare * 第 1 行出现错误: ORA-01476: 除数为 0 ORA-06512: 在 line 4
自定义一个例外(异常)
1 declare 2 pnum number := 0; 3 begin 4 pnum := 1/pnum; -- 会跑出一个叫zero_divide的异常 5 exception 6 when zero_divide then dbms_output.put_line('不能被0除'); 7* end; SQL> / 不能被0除
例: -- 查询50号部门的所有员工的姓名,如果没有查到数据抛出列外。
1 declare 2 cursor cemp is select ename from emp where deptno = 50; 3 pname emp.ename%type; 4 -- 自己定义异常 5 not_emp_data exception; 6 begin 7 open cemp; 8 fetch cemp into pname; 9 if cemp%notfound then 10 dbms_output.put_line('11'); 11 raise not_emp_data; 12 else 13 loop 14 exit when cemp%notfound; 15 dbms_output.put_line(pname); 16 end loop; 17 end if; 18 close cemp; 19 exception 20 when not_emp_data then dbms_output.put_line('没有找到50号部门的数据'); 21* end; SQL> / 11 没有找到50号部门的数据