PL/SQL--游标

PL/SQL–游标

游标概论:游标是一个私有的SQL 工作区域,Oracle 数据库中有两种游标,分别是隐式游标和显式游标,隐式游标不易被用户和程序员察觉和意识到,实际上Oracle 服务器使用隐式游标来解析和执行我们提交的SQL语句;而显式游标是程序员在程序中显式声明的;通常我们说的游标均指显式游标。

SQL%ROWCOUNT 的受最近的SQL 语句影响的行数
SQL%FOUND 的最近的SQL 语句是否影响了一行以上的数据
SQL%NOTFOUND 的最近的SQL 语句是否未影响任何数据
SQL%ISOPEN 为对于隐式游标而言永远为FALSE

DECLARE
  v_employee_id employees.salary%TYPE := 0;
BEGIN

  select salary into v_employee_id 
    from employees 
    where employee_id = 176;

  if SQL%NOTFOUND then--这个没有用,没有找数据时into 处就会出错
   DBMS_OUTPUT.put_line('没找到数据');
  elsif SQL%FOUND then--此处的SQL相当于系统游标
    DBMS_OUTPUT.put_line('找到数据了');--此处的SQL相当于系统游标
  end if;
END;
DECLARE
  v_employee_id employees.salary%TYPE := 176;
BEGIN
  select salary into v_employee_id 
    from employees 
    where employee_id = 1;
exception
  when no_data_found then-- no_data_found 系统预定义异常
    dbms_output.put_line('no data found');
END;

游标使用举例

declare 
  v_name     employees.first_name%type;
  v_salary   employees.salary%type;

  --1.声明游标
  cursor emp_cursor 
    IS select first_name, salary
         from employees;
begin
  --2.打开游标
  open emp_cursor;

  loop
    --3.fetch数据
    fetch emp_cursor --fetch后,游标自行往后移动
      into v_name, v_salary;
    --4.判断数据是否存在
    exit when emp_cursor%ROWCOUNT > 10 
           or emp_cursor%NOTFOUND;
    dbms_output.put_line(emp_cursor%ROWCOUNT || '-:' || v_name || '  ' || v_salary);    
  end loop;
  --5.关闭游标(1.每次异常处理后,都应该关闭游标 2.正常结束后必须关闭。3.显式打开必须显式关闭);
  close emp_cursor;
end;    

如果你觉得像前面那个例子那样对一个游标的遍历很麻烦的话,可以考虑使用For 循环,For 循环省去了游标的: 声明、打开、提取、测试、关闭等语句,对程序员来说很方便,语法如下

declare 
  cursor emp_cursor IS
    select first_name, salary
      from employees;
begin
  for v_row in emp_cursor loop
    dbms_output.put_line(v_row.first_name || v_row.salary);
    exit when emp_cursor%notfound;
  end loop;
end;

游标与记录类型

declare 
  type type_emp IS record
    (v_name varchar2(10),
     v_salary number);

  cursor emp_cursor IS
    select first_name, salary
      from employees;
begin
  for type_emp in emp_cursor loop
    dbms_output.put_line(type_emp.first_name || '--' || type_emp.salary);
    exit when emp_cursor%notfound;
  end loop;
end;

带参数的游标,查询指定部门id的员工

declare 
  cursor emp_cursor(dep_id number) IS
    select *
      from employees
      where department_id = dep_id;
begin 
  for emp in emp_cursor(30) loop
    exit when emp_cursor%NOTFOUND;
    dbms_output.put_line(emp.first_name || '-' || emp.last_name);
  end loop;
end;

where current of cursor_name的使用

declare
  v_dep    departments%rowtype;
  v_emp    employees%rowtype;
  cursor dep_cursor IS
    select * 
      from departments 
      for update;
begin 
  open dep_cursor;

  loop 
    fetch dep_cursor into v_dep;
    exit when dep_cursor%NOTFOUND;

    --似乎只能在更新或者删除的时候使用
    update departments
      set department_name = v_dep.department_name
      where current of dep_cursor;

/*      select *
        from departments
        where current of dep_cursor;*/

    dbms_output.put_line(v_emp.first_name);
  end loop;
end;  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值