二十一、Oracle學習筆記:編寫函式和觸發器
阿新 • • 發佈:2019-02-10
一、函式或過程的選擇
1.如果要進行DML(增刪改),選擇儲存過程
2.如果沒有DML,選擇函式
二、函式
1.格式
create or replace function 函式名(引數1 型別,引數2 型別, 。。。)
return 型別
is
--變數宣告區
begin
--業務邏輯區
return 值;
end;
/
2.例項
--練習,山寨sign函式: --邏輯:判斷某一個數,如果>0,就返回1, --如果<0,返回-1,如果=0,就返回0; create or replace function sgn(a number) return number is begin if a>0 then return 1; elsif a=0 then return 0; else return -1; end if; end; / --select sgn(5) from dual; declare res number; begin res:=sgn(10); if res>0 then dbms_output.put_line('正數'); end if; end; / --練習:比較兩個員工的工資高低 create or replace function sgnsal(id1 number,id2 number) return number is sal1 number; sal2 number; begin select sal into sal1 from emp where empno=id1; select sal into sal2 from emp where empno=id2; if sal1>sal2 then return 1; elsif sal1=sal2 then return 0; else return -1; end if; end; / declare res number; begin res:=sgnsal(7369,7788); if res=1 then dbms_output.put_line('前面的大'); elsif res=0 then dbms_output.put_line('一樣大'); else dbms_output.put_line('後面的大'); end if; end; / --練習:根據部門號計算部門的總工資 create or replace function total(dno number) return number is totalsal number; begin select sum(sal) into totalsal from emp where deptno=dno; return totalsal; end; / select total(10) from dual;
函式的引數型別也和儲存過程一樣規則
--練習:返回兩個數a,b的和,並返回這兩個數 create or replace function abtotal(a in out number,b in out number) return number is begin if a is null then a:=1; end if; if b is null then b:=1; end if; return a+b; end; / declare total number; a number; b number:=10; begin total:=abtotal(a,b); dbms_output.put_line(total); dbms_output.put_line(a); dbms_output.put_line(b); end; /
三、觸發器
1.定義:是ORACLE在發生某些事件時,可以自動觸發並呼叫的PLSQL程式,可以定義在事件上,由事件自動觸發。
2.分類:
(1)系統觸發器
由系統時間觸發的PLSQL程式,比如登入ORACLE\登出ORACLE
(2)DML觸發器
由DML語句觸發的PLSQL程式,如增刪改
3.DML觸發器
(1)語句級觸發器
如果執行完一條DML語句後,希望對整張表的資料進行預算,使用語句級觸發器, 這種觸發器是在DML執行前/執行後觸發的。
--格式: --注意:觸發器是自己呼叫的,不需要呼叫 create or replace trigger 觸發器名 before|after insert|update|delete on 表 declare 宣告變數 begin 處理業務 end; /
--練習:在進行任何增刪改操作後,計算出員工數,員工總薪資,員工平均工資
create or replace trigger mmp
after insert or update or delete on emp
declare
countEmp number;
totalSal number;
avgSal number;
begin
select count(*),sum(sal),trunc(avg(sal),2) into countEmp,totalSal,avgSal from emp;
dbms_output.put_line('總人數 '||countEmp);
dbms_output.put_line('總工資 '||totalSal);
dbms_output.put_line('平均工資'||avgSal);
end;
/
update emp set sal=2500 where empno=7369;
drop trigger mmp;
(2)行級觸發器
如果在執行DML時,希望對當前操作的資料進行處理,那麼可以使用行級觸發器,行級觸發器也是在執行DML之前/之後自動觸發的,在行級觸發器中可以使用行變數,引用到DML所操作的資料,這個行變數是內建的,可以直接使用。
行變數
:new 表示引用的是新增後的行資料
:old 表示引用的是修改/刪除前的行資料
規則
insert語句只有:new,表示插入後的新資料
delete語句只有:old,表示刪除前的舊資料
update語句既有:new也有:old,其中
:new表示修改後的資料,
:old表示修改前的資料
--格式:
create or replace trigger 觸發器名
before|after insert|update|delete on 表
for each row
declare
宣告變數
begin
處理業務
end;
/
--用法:
--變數名.欄位名
--觸發器中不能寫commit
--練習:刪除dept表資料之前,將刪除記錄存入備份表中
create or replace trigger tri_dept
before delete on dept
for each row
declare
begin
insert into dept_bak values(:old.deptno,:old.dname,:old.loc);
end;
/
delete from dept;
select * from dept_bak;
rollback;
--練習:修改員工工資,顯示一下之前和之後的工資
set serveroutput on;
create or replace trigger tri_sal
after update on emp
for each row
declare
begin
dbms_output.put_line('old='||:old.sal||',new='||:new.sal);
end;
/
update emp set sal=4000 where empno=7369;