oracle 10g 学习之游标使用和异常介绍(11)

一、游标

1. 使用游标

要求: 打印出 80 部门的所有的员工的工资: salary: xxx

declare

  --1. 定义游标

  cursor salary_cursor is select salary from employees where department_id = 80;

  v_salary employees.salary%type;

begin

 --2. 打开游标

 open salary_cursor;

 --3. 提取游标

 fetch salary_cursor into v_salary;

 --4. 对游标进行循环操作: 判断游标中是否有下一条记录

while salary_cursor%found loop

      dbms_output.put_line('salary: ' || v_salary);

      fetch salary_cursor into v_salary;

end loop; 

 --5. 关闭游标

 close  salary_cursor;

end;

2. 使用游标的练习: 打印出 manager_id 为 100 的员工的 last_name, email, salary 信息(使用游标, 记录)

declare 

           --声明游标   

           cursor emp_cursor is select last_name, email, salary from employees where manager_id = 100;

          

           --声明记录类型

           type emp_record is record(

                name employees.last_name%type,

                email employees.email%type,

                salary employees.salary%type

           );

          

           -- 声明记录类型的变量

           v_emp_recorde emp_record;

begin

           --打开游标

           open emp_cursor;

          

           --提取游标

           fetch emp_cursor into v_emp_recorde;

          

           --对游标进行循环操作

           while emp_cursor%found loop

                  dbms_output.put_line(v_emp_recorde.name || ', ' || v_emp_recorde.email || ', ' || v_emp_recorde.salary );               

                  fetch emp_cursor into v_emp_recorde;

           end loop;

          

           --关闭游标

           close emp_cursor;

end;

3. 利用游标, 调整公司中员工的工资:

   

    工资范围       调整基数

    0 - 5000       5%

    5000 - 10000   3%

    10000 - 15000  2%

    15000 -        1%

declare

    --定义游标

    cursor emp_sal_cursor is select salary, employee_id from employees;

   

    --定义基数变量

    temp number(4, 2);

   

    --定义存放游标值的变量

    v_sal employees.salary%type;

    v_id employees.employee_id%type;

begin

    --打开游标

    open emp_sal_cursor;

   

    --提取游标

    fetch emp_sal_cursor into v_sal, v_id;

   

    --处理游标的循环操作

    while emp_sal_cursor%found loop

          --判断员工的工资, 执行 update 操作

          --dbms_output.put_line(v_id || ': ' || v_sal);

           

          if v_sal <= 5000 then

             temp := 0.05;

          elsif v_sal<= 10000 then

             temp := 0.03;  

          elsif v_sal <= 15000 then

             temp := 0.02;

          else

             temp := 0.01;

          end if;

          

          --dbms_output.put_line(v_id || ': ' || v_sal || ', ' || temp);

          update employees set salary = salary * (1 + temp) where employee_id = v_id;

                 

          fetch emp_sal_cursor into v_sal, v_id;

    end loop;

    --关闭游标

    close emp_sal_cursor;

end;

使用 decode 函数

update employees set salary = salary * (1 + (decode(trunc(salary/5000), 0, 0.05,

                                                                        1, 0.03,

                                                                        2, 0.02,

                                                                        0.01)))

4. 利用游标 for 循环完成 3.

declare

    --定义游标

    cursor emp_sal_cursor is select salary, employee_id id from employees;

   

    --定义基数变量

    temp number(4, 2);

begin

    --处理游标的循环操作

    for c in emp_sal_cursor loop

          --判断员工的工资, 执行 update 操作

          --dbms_output.put_line(v_id || ': ' || v_sal);

           

          if c.salary <= 5000 then

             temp := 0.05;

          elsif c.salary <= 10000 then

             temp := 0.03;  

          elsif c.salary <= 15000 then

             temp := 0.02;

          else

             temp := 0.01;

          end if;

         

          --dbms_output.put_line(v_id || ': ' || v_sal || ', ' || temp);

          update employees set salary = salary * (1 + temp) where employee_id = c.id;

    end loop;

end;

5. 带参数的游标

declare

    --定义游标

    cursor emp_sal_cursor(dept_id number, sal number) is

           select salary + 1000 sal, employee_id id

           from employees

           where department_id = dept_id and salary > sal;

   

    --定义基数变量

    temp number(4, 2);

begin

    --处理游标的循环操作

    for c in emp_sal_cursor(sal => 10000, dept_id => 80) loop

          --判断员工的工资, 执行 update 操作

          --dbms_output.put_line(v_id || ': ' || v_sal);

           

          if c.sal <= 5000 then

             temp := 0.05;

          elsif c.sal <= 10000 then

             temp := 0.03;  

          elsif c.sal <= 15000 then

             temp := 0.02;

          else

             temp := 0.01;

          end if;

         

          --dbms_output.put_line(c.sal || ': ' || c.id || ', ' || temp);

          update employees set salary = salary * (1 + temp) where employee_id = c.id;

    end loop;

end;

6. 隐式游标: 更新指定员工 salary(涨工资 10),如果该员工没有找到,则打印”查无此人” 信息

begin

         update employees set salary = salary + 10 where employee_id = 1005;

        

         if sql%notfound then

            dbms_output.put_line('查无此人!');

         end if;

end;

二、异常

1. 异常的基本程序: 通过 select ... into ... 查询某人的工资, 若没有查询到, 则输出 "未找到数据"

declare

  --定义一个变量

  v_sal employees.salary%type;

begin

  --使用 select ... into ... 为 v_sal 赋值

  select salary into v_sal from employees where employee_id = 1000;

  dbms_output.put_line('salary: ' || v_sal);

exception

  when No_data_found then

       dbms_output.put_line('未找到数据');

end;

declare

  --定义一个变量

  v_sal employees.salary%type;

begin

  --使用 select ... into ... 为 v_sal 赋值

  select salary into v_sal from employees;

  dbms_output.put_line('salary: ' || v_sal);

exception

  when No_data_found then

       dbms_output.put_line('未找到数据!');

  when Too_many_rows then

       dbms_output.put_line('数据过多!');    

end;

2. 处理非预定义的异常处理: "违反完整约束条件"

declare

  --1. 定义异常    

  temp_exception exception;

  --2. 将其定义好的异常情况,与标准的ORACLE错误联系起来,使用EXCEPTION_INIT语句

  PRAGMA EXCEPTION_INIT(temp_exception, -2292);

begin

  delete from employees where employee_id = 100;

exception

  --3. 处理异常

  when temp_exception then

       dbms_output.put_line('违反完整性约束!');

end;

3. 自定义异常: 更新指定员工工资,增加100;若该员工不存在则抛出用户自定义异常: no_result

declare

  --自定义异常                                  

  no_result exception;  

begin

  update employees set salary = salary + 100 where employee_id = 1001;

  --使用隐式游标, 抛出自定义异常

  if sql%notfound then

     raise no_result;

  end if; 

exception

  --处理程序抛出的异常

  when no_result then

     dbms_output.put_line('更新失败');

end;

原文地址:https://www.cnblogs.com/yxlblogs/p/3468411.html