2年 ago mqzi
姓名: |
郭佳堃 | 学号: |
1507112106 | |
专业: |
商务智能 | 班级: |
商务智能 | |
同组人: |
无 |
实验日期: |
2017/07/04 | |
【实验目的与要求】
掌握Oracle游标的处理机制和方法
掌握异常处理方法
【实验内容与步骤】
由于以本实验中用到数据的删除操作,这会导致数据的损毁,因此,在实验之前需将相关表的数据迁移到处理用表中,以保护原有数据。
将指定表中数据查询的结果移到另一张表中的常用方法是使用Create …As命令创建表并导入数据。语法规则如下:
Create table <表名>
As
–此处写上查询语句
在完成本实验前,用以下语句创建员工薪资表EmpSlary,将原Emp表中的指定数据加载进来:
Create table EmpSal
As
Select empno,ename,sal ,deptno,hiredate
From emp
where sal>1200;
执行完后,请查询empsal表中数据。
请给出查询结果:
将查询结果与原单独执行创建表时所用Select语句对比,理解表数据的复制。
1.隐式游标:
以下程序段通过隐式游标的sql%rowcount属性来获取删除语句执行后被删除的数据行数目,请阅读并理解程序,给出测试结果。
set serveroutput on;
declare
v_delete_count number(3);
begin
delete from empsal where sal<1600; –执行删除语句
v_delete_count := sql%rowcount;
–commit;
dbms_output.put_line(‘总共删除数据:’ || v_delete_count || ‘条’ );
end;
/
给出运行结果:
2.显式游标:
(1)使用显式游标
以下程序实现的是定义游标c_sal,将游标打开并读取第一条记录输出。
阅读并理解以下程序,执行代码,输出结果。
set serveroutput on;
declare
cursor c_sal is
select * from empsal;
v_empsal empsal%rowtype;
begin
open c_sal;
fetch c_sal into v_empsal;
dbms_output.put_line(v_empsal.empno || ‘ ‘ || v_empsal.ename ||’ ‘ || v_empsal.sal);
close c_sal;
end;
/
请给出执行结果:
(2)用显式游标循环取值
循环处理的基本操作是加入循环条件,并以c_sal%notfound作为结束判定条件。
—显示游标循环取值:
set serveroutput on;
declare
cursor c_sal is
select * from empsal;
v_empsal empsal%rowtype;
begin
open c_sal;
loop
fetch c_sal into v_empsal;
exit when c_sal%notfound;
dbms_output.put_line(v_empsal.empno || ‘ ‘ || v_empsal.ename ||’ ‘ || v_empsal.sal);
end loop;
close c_sal;
end;
/
给出运行结果:
练习-1:创建一个PL/SQL块,声明一个游标,从EmpSlary表中选择姓名,薪水和雇佣日期。从游标检索每一行,如果雇员的薪水大于5000元,而且雇佣日期在1992年01月31日之前,则显示雇员的具体信息。
写出程序源码:
Declare
Cursor Xx Is Select * From Empsal;
V_Empsal Empsal%Rowtype;
Begin
Open Xx;
Loop
Fetch Xx Into V_Empsal;
Exit When Xx%Notfound;
If V_Empsal.Sal>5000 And V_Empsal.Hiredate < ’31-1月-92′ then
dbms_output.put_line(v_empsal.ename || v_empsal.sal);
end if;
end loop;
close xx;
end;
给出运行测试结果:
练习-2:创建一个PL/SQL块,声明一个游标。将与EmpSlary数据表中sal相同类型的一个参数传递给此游标。用此参数打开上述的游标。将薪水值大于此参数(如:3000)的雇员和有关信息检索到该游标中,并且显示这些雇员的具体信息。
写出程序源码:
同上
给出运行测试结果:
同上
练习-3:创建一个PL/SQL块,为部门10的用户加薪。薪水低于1000美元的雇员加薪15%,薪水等于或高于1000美元的雇员加薪10%。使用含for update子句的游标,以及通过for 循环的where current of 子句实现加薪处理。(要求测试结果中给出测试前表中相关值和程序执行完成后表中数据相关值,以便比对验证)
写出程序源码:
Declare
Cursor Xx Is
Select
*
From
Empsal
Where Deptno=10
For
Update
Of Sal;
V_Temp Empsal%Rowtype;
V_Temp1 Empsal%Rowtype;
Begin
For V_Temp1 In Xx Loop
Dbms_Output.Put_Line(V_Temp1.Ename ||‘ ‘|| V_Temp1.Sal);
End
Loop;
For V_Temp In Xx Loop
If V_Temp.Sal<1000
Then
Update
Empsal
Set Sal=V_Temp.Sal*1.15
WHERE
CURRENT
OF XX;
Elsif V_Temp.Sal>1000
Then
Update
Empsal
Set Sal=V_Temp.Sal*1.1
WHERE
CURRENT
OF XX;
End
If;
End
Loop;
Dbms_Output.Put_Line(‘更新后‘);
For V_Temp1 In Xx Loop
Dbms_Output.Put_Line(V_Temp1.Ename ||‘ ‘|| V_Temp1.Sal);
End
Loop;
End;
给出运行测试结果:
阅读并理解以下程序,掌握异常处理的一般形式,给出运行结果。
1.异常处理示例:
SET SERVEROUTPUT ON
DECLARE
v_name VARCHAR2(10);
n_sal NUMBER(8,2);
BEGIN
SELECT Ename,sal INTO v_name,n_sal –通过查询赋值
FROM empsal
WHERE Ename=’KING’;
DBMS_OUTPUT.PUT_LINE(‘ KING : SALARY :’ || n_sal);
EXCEPTION
–注意:当多个exception在exception段中出现,只执行一个,之后直接跳到end。
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE(‘没找到满足条件的数据’);
WHEN TOO_MANY_ROWS THEN
DBMS_OUTPUT.PUT_LINE(‘查询得到的数据行过多’);
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(‘ERROR!其他问题’);
END;
给出运行结果:
测试1:将代码中的查询条件WHERE Ename=’KING’;改为WHERE sal>=2000;,执行代码,结出测试结果。
测试2:将代码中的查询条件WHERE Ename=’KING’;改为WHERE Ename=’orange’;,执行代码,结出测试结果。
测试3:将代码中的查询条件WHERE Ename=’KING’;故意写错(如:改为WHERE name=’ KING ‘;),执行代码,结出测试结果。
对比以上测试1到测试3的结果,熟悉并理解异常处理的基本方法。
使用游标逐行处理EmpSal中数据,计算EmpSal表中所有雇员的所得税总和。假设所得税为累进税率,所得税算法为:工资收入为0-2000为免税;收入2000-3000者,超过2000的部分税率10%;3000-4000者超过3000部分按20%税率计算;4000-5000者超过4000部分按30%税率计算;5000以上收入,超过5000部分按40%税率计算。
写出程序源码:
Declare
Cursor Xx Is
Select
*
From
Empsal;
V_Temp Number;
V_Temp1 Empsal%Rowtype;
Begin
For V_Temp1 In Xx Loop
If V_Temp1.Sal >
2000
And V_Temp1.sal<3000
Then
V_Temp:=V_Temp1.Sal*0.1;
Elsif V_Temp1.Sal >
3000
And V_Temp1.sal <
4000
Then
V_Temp:= V_Temp + V_Temp1.Sal*0.2;
Elsif V_Temp1.Sal >
4000
And V_Temp1.sal <
5000
Then
V_Temp:= V_Temp+ V_Temp1.Sal*0.3;
Elsif V_Temp1.Sal >
5000
Then
V_Temp:= V_Temp+ V_Temp1.Sal*0.4;
End
If;
End
Loop;
dbms_output.put_line(V_Temp);
End;
给出运行测试结果:
Previous PL/SQL编程基础(I)
Next 过程、函数和程序包