1. 程式人生 > >Oracle學習第四天

Oracle學習第四天

PL/SQL

1.例外
例外是程式設計語言提供的一種功能,用來增強程式的健壯性和容錯性。
①系統例外
No_data_found(沒有找到資料)
Too_many_rows(select...into語句匹配多個行)
Zero_Divide(被零除)
Value_error(算術或轉換錯誤)
Timeout_on_resource(在等待資源時發生超時)


exception
when too_many_rows then ...;
when others then...;
②自定義例外
丟擲例外 :raise




例:
--查詢50號部門的員工姓名
set serveroutput on
declare 
--定義游標,代表50號部門的員工姓名
cursor cemp is select ename form emp where deptno=50;
peanme emp.ename%type;
--自定義例外

no_emp_found exception;
begin
--開啟游標
open cemp;
--直接取一個員工的姓名
fethc cemp into pename;
if cemp%nofound then
--丟擲例外
raise no_emp_found;
end if;
--關閉游標
--oracle自動啟動pmon(process monitor)
close cemp;
exception
when no_emp_found then dbms_output.put_line("沒有找到員工");
when others then dbms_output.put_line("其他");
end;
/

綜合案例

1.統計每年入職的員工人數
set serveroutput on
declare
--定義游標
cursor cemp is select to_char(hiredate,'yyyy') from emp;
phiredate varchar2(4);
--每年入職的員工人數
count80 number:=0;
count81 number:=0;
count82 number:=0;
count87 number:=0;
begin
--開啟游標
open cemp;
loop
--取出一個員工的入職年份
fetch cemp into phiredate;
exit when cemp%notfound;
--判斷入職年份
if phiredate='1980'then count80:=count80+1;
elsif phiredate='1981' then count81:=count81+1;
elsif phiredate='1982' then count82:=count82+1;
else count87:=count87+1;
end if;
end loop;
close cemp;
end;
/
2.員工漲工資問題
set serveroutput on
declare
--定義游標
cursor cemp is select empno,sal from emp order by sal;
pempno emp.empno%type;
--漲工資的人數
countEmp number:=0;
--漲工資後的總額
salTotal number;
begin
--得到工資的總額的初始值
select sum(sal) into salTotal from emp;
open cemp;
loop
--1.工資總額>5w
exit when salTotal >50000;
--取一個員工漲工資
fetch cemp into pempno,psal;
--%outfound
exit when cemp%notfound;
if(salTotal+psal*1.1)<50000 then
--漲工資
update empp set sal=sal*1.1 where empno=pempno;
--人數+1
countEmp:=countEmp+1;
-漲工資後的總額
salTotal:=salTotal+psal*0.1;
else exit;
end if;
end loop;
close cemp;
commit;
end;
/
3.操作兩張表的員工漲工資問題
set serveroutput on
declare 
--定義游標部門
cursor cdept is select demtno from dept;
pdeptno dept deptno%type;
--部門中員工的薪水
cursor cemp(dno number) is select sal from emp where deptno= dno;
--每個段的員工人數
count1 number;
count2 number;
count3 number;
--每個部門的工資總額
saltotal number;
begin
--開啟部門的游標
open cdept;
--取出一個部門
loop
fetch cdept inot pdeptno;
exit when cdept%notfound;
--初始化的工作
count1:=0;
count2:=0;
count3:=0;
--部門工資總額
select sum(sal) into saltotal from emp where deptno=pdeptno;
--取部門中員工的薪水
open cemp(pdeptno);
loop
--取一個員工的薪水
fetch cemp into psal;
exit when cemp%notfound
--判斷薪水的範圍
if psal<3000 then count1:=count1+1;
elsif psal>=3000 and psal< 6000 then count2:=count2+1;
else count3:=count3+1;
end if;
end loop;
close cemp;
--儲存當前部門的結果
insert into msg values(pdeptno,count1,count2,count3,nvl(SALTOTAL,0));
end loop;
close cdept;
commit;
end;
/
nvl(a,b):如果a為null就取b,如果a不為null就取本身


4.成績統計
set serveroutput on
declare
--系的游標
cursor cdept is select dno,dname from dep;
pdno dep.dno%type;
pdname dep.dname%type;

--成績游標
cursor cgrade(coursename varchar2,depno number)
is select grade from sc where cno=(select cno from course where cname=coursename) and sno in (select sno from student where dno=depno);
pgradge sc.grade%type;
--每個段的人數
count1 number,
count2 number,
count3 number;
-每個系選修了“大學物理”學生的平均成績
avggrade number;

--課程名稱
pcourseName varchar2:='大學物理';
begin
open cdept;
loop
--取一個系的資訊
fetch cdept into pdno,pdname;
exit when cdept%notfound;
--初始化工作
count1:=0,
count2:=0,
count3:=0;
--系的平均成績
select avg(grade) into avggrade from sc where scno=(select cno from course where cname=pcourseName) and sno in(select sno from student where dno=pdno);
--取系中,選修了大學物理的學生成績
open cgrade(pcourseName,pdno);
loop
-取一個學生的成績
fetch cgrade into pgrade;
exit when cgrade%notfound;
--判斷成績範圍;
if pgrade <60 then count1:=count1+1;
elsif pgrade>=60 and pgrade<85 then count2:=count2+1;
else count3:=count3+1;
end if;
end loop;
close cgrade;
--儲存當前結果
insert into msg1 values(pcourseName,pdno,count1,count2,count3)
end loop;
close cdept;
commit;
end;
/