1. 程式人生 > >oracle學習筆記(二十) 子程式——函式與觸發器

oracle學習筆記(二十) 子程式——函式與觸發器

子程式——函式

語法

之前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;