Oracle 游标

--无论是隐式游标,还是显示游标,均有%ISOPEN,%FOUND,%NOTFOUND,%ROWCOUNT四个属性
--隐式游标
/*
       所有DML语句(主要用在update/delete)为隐式游标,通过隐式游标属性可以获取SQL语句信息。
*/
--%FOUND : 用来判断当前游标是否指向有效的一行,若是则为true,否则为false

begin
  delete from t_emp where empno = 7369;
  if sql%found then
     dbms_output.put_line('7369用户信息删除成功');
  else
     dbms_output.put_line('7369用户信息不存在');
  end if;
end;
--%NOTFOUND: 与%FOUND类似,但其值确刚好相反
begin
  delete from t_emp where empno = 99999;
  if sql%notfound then
     dbms_output.put_line('99999用户信息不存在');
  end if;
end;
--%rowcount 记录了游标抽取过的记录行数,也可以理解为当前游标所在的行号
begin
  delete from t_emp where empno > 10;
     dbms_output.put_line('受影响的行数:'||sql%rowcount);
end;

--显式游标
/*
 用户显示声明的游标,即指定结果集。当查询返回结果超过一行时,就需要一个显式游标。
*/

declare
   --定义复合(emp行类型)类型变量
   rec emp%rowtype;
   --声明显示游标
   cursor cur_emp is
   select * from emp where sal>2500; 
begin
  open cur_emp; -- 开启游标
  loop -- 循环提取游标
    fetch cur_emp into rec; -- 提取游标的一行数据赋值给rec
    exit when cur_emp%notfound; -- 当没有找到记录时退出循环
    dbms_output.put_line(cur_emp%rowcount||'.雇员名称:'||rec.ename||'工资:'||rec.sal);
 end loop;
--%isopen 判断游标是否打开,若是则为true,否则为false
 if cur_emp%isopen then -- 判断游标是否打开,如果是则关闭游标
    close cur_emp; --关闭游标
 end if;
end;

-- 参数游标


declare
   --定义复合(emp行类型)类型变量
   rec emp%rowtype;
   --部门编号
   v_deptno number;
   --声明显示游标
   cursor cur_emp(p_deptno number) is --根据部门编号查询
   select * from emp where deptno = p_deptno; 
begin
  v_deptno:='&请输入部门编号';
  open cur_emp(v_deptno); -- 开启游标
  loop -- 循环提取游标
    fetch cur_emp into rec; -- 提取游标的一行数据赋值给rec
    exit when cur_emp%notfound; -- 当没有找到记录时退出循环
    dbms_output.put_line(cur_emp%rowcount||'.雇员名称:'||rec.ename||'工资:'||rec.sal);
 end loop;
--%isopen 判断游标是否打开,若是则为true,否则为false
 if cur_emp%isopen then -- 判断游标是否打开,如果是则关闭游标
    close cur_emp; --关闭游标
 end if;
end;


--REF游标(有称为动态游标,隐式游标和显示声明游标又称为静态游标)
/*
 动态关联结果集
 给指定部门下的员工涨薪水20%

*/

 

declare 
     type cus_cur is ref cursor; -- 声明一个ref游标类型
     var_cur cus_cur; -- 声明ref游标类型的变量
     v_emprow emp%rowtype; -- 定义emp 行类型变量
     v_deptno number := &v_deptno;
begin
     -- 打开游标,并指定查询结果集
     open var_cur for 'select * from t_emp where deptno = :v_deptno_var' --:v_deptno_var 设置参数
     using v_deptno; -- 通过using 替换参数
     loop -- 循环游标
       fetch var_cur into v_emprow; -- 提取游标
       exit when var_cur%notfound; -- 如果提取到了最后一行则退出循环
       update t_emp set sal = sal + sal * 0.2 where empno = v_emprow.empno; -- 修改员工薪水
       --打印加薪信息
       dbms_output.put_line('员工姓名:'||v_emprow.ename || ' 已经加薪');
     end loop;
     close var_cur; -- 关闭游标
commit;
end;

使用显示游标的方式输出:员工编号、员工姓名、部门名称,职务、薪水(数据使用:emp、dept表)

方法一:先创建视图,然后通过游标输出

create or replace view vi_emp_dept(empno,ename,dname,ejob,esal)
as select e.empno,e.ename,d.dname,e.job,e.sal from emp e,dept d
where e.deptno=d.deptno;

declare
       v_emp_dept scott.vi_emp_dept%rowtype;
       cursor c_emp is select * from vi_emp_dept;      
begin
       open c_emp;
       loop
         fetch c_emp into v_emp_dept;
         exit when c_emp%notfound;
         dbms_output.put_line(v_emp_dept.empno||' '||v_emp_dept.ename||' '||v_emp_dept.dname||' '||v_emp_dept.ejob||' '||v_emp_dept.esal);    
       end loop;
       if c_emp%isopen then 
         close c_emp;
       end if;
end;
方法二:定义一个类型变量,然后用游标输出

declare
  type t_emp_dept is record(
       empno scott.emp.empno%type,
       ename scott.emp.ename%type,
       dname scott.dept.dname%type,
       ejob  scott.emp.job%type,
       esal  scott.emp.sal%type
       );      
       v_emp_dept t_emp_dept;
       cursor c_emp is select e.empno,e.ename,d.dname,e.job,e.sal from emp e,dept d where e.deptno=d.deptno;      
begin
       open c_emp;
       loop
         fetch c_emp into v_emp_dept;
         exit when c_emp%notfound;
         dbms_output.put_line(v_emp_dept.empno||' '||v_emp_dept.ename||' '||v_emp_dept.dname||' '||v_emp_dept.ejob||' '||v_emp_dept.esal);    
       end loop;
       if c_emp%isopen then 
         close c_emp;
       end if;
end;

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值