currentrecord mycursor%Rowtype; Begin
temp_Examsal:=3000; temp_Examsal:=800; --打开游标
If mycursor%Isopen Then
dbms_output.put_line('该游标已经打开了,正在关闭!'); Close mycursor; Open mycursor; Else
dbms_output.put_line('游标关闭,正在打开!'); Open mycursor; End If; --读取数据
Fetch mycursor Into currentrecord; If mycursor%Found Then
dbms_output.put_line('游标已经取到数据,查询结果是:'); dbms_output.put_line(to_char(currentrecord.ename)); Else
dbms_output.put_line('没有要查询的结果!'); End If;
--读取记录总条数 Loop
Fetch mycursor Into currentrecord; Exit When mycursor%Notfound; End Loop;
dbms_output.put_line('查结果总共有:'||mycursor%Rowcount); --关闭游标
If mycursor%Isopen Then
dbms_output.put_line('正在关闭游标,程序正常结束!'); Close mycursor; End If; End;
给出运行结果:
4.9.异常处理:
阅读并理解以下程序,掌握异常处理的一般形式,给出运行结果。 0.准备测试表和数据:
drop table sm_emp_Exam; CREATE TABLE sm_emp_Exam( no char(4), name char(10), salary number(6,2), phone char(8) );
第 21 页 共 31 页
--insert TOM
INSERT INTO sm_emp_Exam VALUES ('001','TOM',999.99,'62543678'); commit;
--insert TOM again
INSERT INTO sm_emp_Exam VALUES ('002','TOM',999.99,'62543678'); commit;
DELETE FROM sm_emp_Exam WHERE name='TOM'; commit;
1.异常处理示例:
SET SERVEROUTPUT ON ---named exception test DECLARE
v_name VARCHAR2(10); n_sal NUMBER(8,2); BEGIN
SELECT name , salary INTO v_name , n_sal FROM sm_emp_Exam WHERE name='TOM';
DBMS_OUTPUT.PUT_LINE('TOM : SALARY :' || n_sal); EXCEPTION
--注意:当多个exception在exception段中出现,只执行一个,之后不直接跳到end。 WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('NO EMP_EXAMLOYEE NAMED TOM'); WHEN TOO_MANY_ROWS THEN
DBMS_OUTPUT.PUT_LINE('TOO MANY TOM'); WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('ERROR!'); END;
给出运行结果:
第 22 页 共 31 页
4.10. 综合练习
以下实验中用到的Exam_EMP表结构与内容与Scott模式下的表Emp相同,请用Create ?As命令创建并导入数据。而后,参照前面实验,完成以下实验练习。 create table Exam_emp as select * from emp;
1. 计算Exam_EMP表中COMM最高与最低的差值,COMM值为空时按0计算。
写出程序源码: Declare
var1 number; var2 number;
val_comm number; begin
select max(nvl(comm,0)) into var1 from Exam_emp; select min(nvl(comm,0)) into var2 from Exam_emp; val_comm:=var1-var2;
dbms_output.put_line(val_comm); end;
给出运行测试结果:
2. 根据表Exam_EMP中deptno字段的值,为姓名为‘JONES’的雇员修改工资;若部门
号为10,则工资加100;部门号为20,加200;其他部门加400。 写出程序源码: declare c1 number; c2 number; begin
select deptno into c1 from emp
where ename='JONES'; if c1=10 then c2:=100;
elsif c1=20 then c2:=200; else c2:=400; end if;
update emp set sal=sal+c2 where ename='JONES';
第 23 页 共 31 页
commit; end;
给出运行测试结果:
3. 计算显示部门人数最多的部门号、人数、工资总和,以及部门人数最少的部门号、人数、
工资总和。
写出程序源码:
select deptno,PersonNum,TotalSal
from (select deptno,count(*) PersonNum,sum(nvl(sal,0)+nvl(comm,0)) TotalSal from exam_emp group by deptno order by PersonNum desc) where rownum< =1;
给出运行测试结果:
4. 计算Exam_EMP中所有雇员的所得税总和。假设所得税为累进税率,所得税算法为:
工资收入为0-2000为免税;收入2000-3000者,超过2000的部分税率10%;3000-4000者超过3000部分按20%税率计算;4000-5000者超过4000部分按30%税率计算;5000以上收入,超过5000部分按40%税率计算。(请查阅累进税率的概念) 写出程序源码: DECLARE
CURSOR c1 IS
SELECT sal FROM emp; sum_xx number; BEGIN
sum_xx:=0;
FOR r1 IN c1 LOOP
IF r1.sal>0 and r1.sal<=2000 THEN sum_xx:=sum_xx;
ELSIF r1.sal >2000 and r1.sal<=3000 THEN sum_xx:=sum_xx+(r1.sal-2000)*0.1;
ELSIF r1.sal>3000 and r1.sal<=4000 THEN
第 24 页 共 31 页
sum_xx:=sum_xx+(r1.sal-3000)*0.2;
ELSIF r1.sal>4000 and r1.sal<=5000 THEN sum_xx:=sum_xx+(r1.sal-4000)*0.3; ELSE
sum_xx:=sum_xx+(r1.sal-5000)*0.4; END IF; END LOOP;
dbms_output.put_line('所有雇员的所得税总和:'||sum_xx); END; /
给出运行测试结果:
5. 假设有个表如Exam_EMP,未建立主键,含有多条记录重复(列值完全相同),试编制
一个PL/SQL,将多余的重复记录删除。 写出程序源码: Set serveroutput on variable a1 number; begin
:a1:=1000; end; / begin
dbms_output.put_line('a1 de zhi wei:'||:a1); end;
/给出运行测试结果:
参照前面实验和教材,完成以下实验作业,给出源程序和测试结果。
6. 计算EMP表中所有雇员的所得税总和。假设所得税为累进税率,所得税算法为:工资
收入为0-2000为免税;收入2000-3000者,超过2000的部分税率10%;3000-4000者超过3000部分按20%税率计算;4000-5000者超过4000部分按30%税率计算;5000以上收入,超过5000部分按40%税率计算。 写出程序源码: DECLARE
第 25 页 共 31 页