一、游标
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;