天天看點

存儲過程 觸發器

在學習觸發器以及存儲過程中時遇到了一些典型的例題,在這裡和大家分享一下。

碼字不易,點個關注給個贊吧

1.       定義過程,根據雇員編号找到雇員姓名及工資。(10分)

代碼:

create or replace procedure pro_emp2(v_empno in emp.empno%type)

is

v_ename emp.ename%type;

begin

select ename into v_ename from emp where empno=V_empno;//需要使用查詢語句方可觸發異常。

delete from emp 

where empno=v_empno;

--dbms_output.put_line('已成功删除資料');

exception 

when no_data_found then

dbms_output.put_line('查無此人');

end;

executepro_emp(7566);

2.       建立一個功能為:删除給定職工号的職工資訊的存儲過程,并調用該存儲過程。(10分)

代碼:

create or replace procedure pro_emp(var_empno in emp.empno%type)is

begin

delete from emp whereempno=var_empno;

exception  //notfound 異常處理

when no_data_foundthen

dbms_output.put_line('無資料記錄');

end;

executepro_emp(8888);

3.       利用存儲過程增加部門資訊。(10分)

代碼:

create or replace procedure pro_dept(var_deptno in dept.deptno%type,var_dname in dept.dname%type,var_loc in dept.loc%type)is

begin   

 insert into dept(deptno,dname,loc)values(var_deptno,var_dname,var_loc);

 dbms_output.put_line('編号為'||var_deptno||'的部門資訊被插入');

end;

4.      建立一個過程avg_sal,用于輸出emp表中某個部門的平均工資,并在PL/SQL匿名塊中調用該過程輸出20号部門的平均工資。要求:利用輸入輸出參數實作。(10分)

代碼:

create or replace procedure pro_emp(var_deptno in emp.deptno%type)is

avg_sal emp.sal%type;

begin

 select avg(sal) into avg_sal from emp wheredeptno=var_deptno;

 dbms_output.put_line('編号為'||var_deptno||'的部門的平均工資為'||avg_sal);

 exception

when no_data_foundthen

dbms_output.put_line('無資料記錄');

end;

5.      從雇員基本資訊表(EMP)中統計各部門(DEPTNO)人數後,将結果輸出。

--執行存儲過程結果如下圖所示:(10分)

代碼:

create or replace procedure pro_emp is   //統計各部門說明有多條記錄故使用遊标

cursor cur_emp isselect deptno ,count(empno) num from emp group by deptno;

begin

for x in cur_emp loop

dbms_output.put_line('部門号 '||x.deptno||'  人數  '||x.num);

end loop;

end;

execute pro_emp;

6.       編寫一個“過程”,可以輸入一個雇員名,如果該雇員的職位為PRESIDENT就給他的工資增加1000,如果該雇員的職位為MANAGER,就給他的工資加500,其他職位的雇員工資增加200。并在SQL*PLUS中調用該過程來修改FORD的工資。(10分)

代碼:

create or replace procedure pro_emp(var_ename in emp.ename%type) is

var_job emp.job%type;

begin

select job intovar_job from emp where ename=var_ename;

dbms_output.put_line('該員工的職務為'||var_job);

if var_job='PRESIDENT' then

update emp setsal=sal+1000 where ename=var_ename; dbms_output.put_line(var_ename||'的工資增加了1000');

elsif var_job='MANAGER' then

update emp setsal=sal+500 where  ename=var_ename;dbms_output.put_line(var_ename||'的工資增加了500');

else update emp setsal=sal+200 where  ename=var_ename;dbms_output.put_line(var_ename||'的工資增加了200');

end if;

 exception

when no_data_foundthen

dbms_output.put_line('無資料記錄');

end;

executepro_emp('mldn');

7.       利用觸發器,在星期一、周末及每天下班時間(每天9:00以前、18:00以後)後不允許更新emp資料表。(10分)

注意:如果想“此時”驗證觸發器效果,對上述觸發器進行相應修改

代碼:

create or replace trigger emp_time

before update or insert or delete

on emp

begin

if

to_char(sysdate,'DY')in('星期一','星期六','星期日') //擷取目前系統時間

or to_char(sysdate,'HH24')<'9'

and to_char(sysdate,'HH24')>'18'

then raise_application_error(-20009,'目前時間無法對emp表進行操作');

end if;

end ;

insert into emp(empno,ename,job,hiredate,sal,comm,mgr,deptno)

 values(8997,'mldn','MANAGER',SYSDATE,2000,500,7369,40);

存儲過程 觸發器

運作結果即如圖所示,會啟用報錯程式

8.       編寫觸發器,在每天12點以後,不允許修改雇員工資和獎金。(10分)

代碼:

create or replace triggeremp_time1

before update of sal,comm   //針對表中某一屬性列作用用of

on emp

begin

if

to_char(sysdate,'HH24')>'8'

then raise_application_error(-20008,'目前時間無法對emp表進行修改工資或獎金的操作操作');//報錯處理

end if;

end ;

9.       建立一個行級觸發器CASCADE_DEL_UPD,當修改部門編号時,EMP表的相關行的部門編号也自動修改;當删除部門表中某個部門号是,EMP表該部門号的員工一并删除。(10分)

對于INSERT語句, 隻有NEW是合法的;

對于DELETE語句,隻有OLD才合法;

對于UPDATE語句,NEW、OLD可以同時使用。

代碼:

create or replace trigger CASCADE_DEL_UPD

before  update of deptno or delete

on dept

for each row

declare

begin

if deleting  then delete from emp where deptno=:old.deptno;  end if;  //如果進行删除操作就先将emp表中的deptno資訊删除

if updating then  update emp set deptno=:new.deptno wheredeptno=:old.deptno;  end if;

end CASCADE_DEL_UPD;

create or replace trigger cas_update

before update of deptno or delete

on dept

for each row

begin

case

when updating('deptno') then update emp set deptno=:new.deptno where deptno=:old.deptno;

else delete from emp where deptno=:old.deptno;

end case;

end;

将dept表中40号變為60号

update dept setdeptno=60 where deptno=40

delete from deptwhere deptno=40;

10.   建立一個顯示員工編号、員工姓名、所在部門号及部門名的視圖。利用觸發器實作向該視圖中添加記錄的操作。(10分)

代碼:

create view view_emp

as select empno,ename,dept.deptno,dname

from emp,dept

where emp.deptno=dept.deptno;

create or replace trigger tir_insert_view

instead of insert

on view_emp

for each row

declare

row_deptdept%rowtype;

begin

select * intorow_dept from dept where deptno=:new.deptno;

if sql%notfound then

insert intodept(deptno,dname)

values(:new.deptno,:new.dname);

end if;

insert into emp(empno,ename,deptno)

values(:new.empno,:new.ename,:new.deptno);

end tir_insert_view;

建立觸發器,對emp表中的員工工資隻能上漲不能降低

create or replace trigger emp_update

after update of sal

on emp

for each row

begin

if :new.sal<:old.sal then raise_application_error(-20008,'員工工資隻能升不能降');

else dbms_output.put_line('員工工資已被提升');

end if;

end;

存儲過程 觸發器

其運作結果如圖所示,并非運作錯誤

建立觸發器,對emp表中資料進行删除備份

create or replace trigger save_emp

before delete 

on emp

for each row

begin

if deleting then

dbms_output.put_line('已成功将被删除資料備份到empsave表中');

insert into empsave values(:old.empno,:old.ename,:old.job,:old.mgr,:old.hiredate,:old.sal,:old.comm,:old.deptno);

end if;

end;

create  table empsave as select * from emp where 1=2; //參照emp表建立empsave,但隻是使用其屬性,不用其資料

delete from emp where empno=8913;

 select * from emp; 

 insert into emp(empno,ename,job,hiredate,sal,comm,mgr,deptno)

  values(8913,'mldn','MANAGER',SYSDATE,2000,500,7369,30);