oracle學習筆記(二十) 子程式——函式與觸發器
阿新 • • 發佈:2019-06-03
子程式——函式
語法
之前select語句中使用的函式,都是SQL內建函式,我們可以通過自定義函式更滿足我們的需要。
自定義函式的語法和儲存過程差不多。
create [or replace] $funtion_name$[(引數..)]
return $data_type$
is/as
begin
return result;
[exception]--異常處理
end $funtion_name$;
/
注意點:
- 函式只能接收引數模式只能是in,預設不寫即可
- 函式引數和返回結果的型別只能是SQL的標準型別,PL/SQL特有型別不可使用(如boolean,string..)
使用自定義函式
SQL函式都是在select語句中使用,這也是函式與儲存過程過程的區別
--編寫一個函式獲得指定部門的平均工資。 create or replace function avg_sal(p_deptno employee.sal%type) return employee.sal%type is v_avg_sal employee.sal%type; begin select avg(nvl(sal,0) into v_avg_sal from employee where deptno=p_deptno; return v_avg_sal; end avg_sal; / --select語句使用 select dname,avg_sal(deptno) from department;
觸發器
觸發器,當滿足某種事件時候系統會自動執行(隱式執行)
語法
create or replace trigger 觸發器名
觸發時間(BEFORE|AFTER) 觸發事件(INSERT OR UPDATE OR DELETE) [OF 列名] ON 觸發物件(表、檢視等)
觸發頻率[for each row] --沒有for each row的話預設為語句級觸發器
when (觸發條件)
declare
--宣告變數部分
begin
--執行部分
end 觸發器名;
說明
觸發事件:
- DML語句(INSERT, UPDATE, DELETE語句對錶或檢視執行資料處理操作)、
- DDL語句(如CREATE、ALTER、DROP 語句在資料庫中建立、修改、刪除模式物件)、資料庫系統事件(如系統啟動或退出、異常錯誤)、
- 使用者事件(如登入或退出資料庫)
觸發頻率:
- 語句級 語句結束,觸發器結束,只執行一次
- 行級 每行又滿足觸發器條件,都會執行一次觸發器
觸發條件:
NEW和OLD都是參考物件
- NEW 代表新的資料物件(record)
OLD 代表原來的資料物件(record)
insert操作只有NEW, 代表著要插入的新記錄
delete操作只會有OLD,代表著要刪除的該條記錄
update操作NEW 和 OLD 都有
PS:PLSQL使用的時候需要使用:
,when裡面則不需要使用
條件量( boolean型 ):
可以在when語句或者是PLSQL中使用
- inserting: 代表做的是insert操作
- updating: 代表做的是update操作
- deleting: 代表做的是delete操作
例子
--示例 1:當向employee插入資料時自動填充(生成)主鍵值,(使用序列)
create or replace trigger trg_auto_generate_pk
before insert on employee
for each row --行級觸發器,每一行滿足條件觸發
when(NEW.empno is null) --當插入的資料主鍵為空,自動生成,NEW表示當前INSERT的資料,不需要使用:
declare
empno number;
begin
--之前建立的序列
select emp_seq.nextval into empno from dual;
if inserting then
:NEW.empno := empno;--使用:引用
end if;
end trg_auto_generate_pk;
/
/*
示例 2:當刪除資料時,自動備份
a. 建立備份表
b. 建立觸發器
*/
--這裡也可以使用動態SQL建立表
--建立備份表,只複製結構,不復制資料
create table employee_dump
as select * from employee where 1=2;
--建立觸發器
create or replace trigger trg_backup_employee
after delete on employee
for each row
when(OLD.empno is not null)
declare
begin
insert into employee_dump values(:old.empno,:old.ename,:old.job,:old.mgr,:old.hiredate,:old.sal,:old.comm,:old.deptno);
commit;
exception
when others then
null; --還可以把異常的資訊插入到日誌表
end trg_backup_employee;
/
--禁用觸發器:disable
alter trigger trg_backup_employee disable;
--啟用觸發器:enable
alter trigger trg_backup_employee enable;
--禁用某個表上所有的觸發器:disable all triggers;
alter table employee disable all triggers;
--刪除觸發器
drop trigger trg_backup_employee;