1、觸發器的概述
觸發器是當特定事件出現時自動執行的存儲過程,特定事件可以是執行更新的DML語句和DDL語句;觸發器不能被顯式調用,只有當觸發條件成立時,觸發器纔會被觸發。
-
觸發器的功能:
- 自動生成數據
自定義複雜的安全權限(完整性約束)
提供審計和日誌記錄 (記錄日誌信息到所規定的表)
啓用複雜的業務邏輯
- 自動生成數據
- 觸發事件:
insert update delete create alter drop logon logoff startup startdown - 觸發級別:
行觸發、對觸發事件影響的每一行都執行一次觸發器,
語句觸發、觸發事件只觸發一次,不能訪問受觸發器影響的每一行的值,即無論這條sql語句影響多少條記錄,觸發器都觸發一次。 - 觸發事件:
before 在指定事件發生之前執行觸發器
after 在指定事件發生之後執行觸發器 - 禁止使用:
在觸發器中禁止使用rollback、 commit、savepoint、create 、drop、alter
2、創建觸發器的語法
CREATE [OR REPLACE] TRIGGER trigger_name
AFTER | BEFORE | INSTEAD OF
[INSERT] [[OR] UPDATE [OF column_list]] -- 觸發器引起動作
[[OR] DELETE]
ON table_or_view_name -- 指明作用對象:表、視圖…
[REFERENCING {OLD [AS] old / NEW [AS] new}] -- :old :new的作用
[FOR EACH ROW] --行極?表級?觸發器
[WHEN (condition)] -- 滿足條件才觸發
pl/sql_block;
解釋:
- AFTER | BEFORE 建立在表上 INSTEAD OF 建立在視圖上
- [FOR EACH ROW] 有了該句就是行級觸發器,沒有就是表級觸發器。
- 如果在觸發器的PL*SQL中使用:new(表示新插入的那行記錄) 和:old(表示過去的值)時, 只能使用在行級觸發器中,即就是for each row 存在的時候。
當使用insert的時候,:new存在 :old不存在
當使用delete的時候,:new不存在 :old存在
當使用update的時候,:new存在 :old存在
舉例: 假設存在一張名爲student的學生表,裏面包含學號列、姓名列、年齡列;我們現在要求用觸發器來約束插入表中的學號不得爲負。(trig1實現)
若爲負變爲正。(trig2實現)
set serveroutput on
crate or replace trigger trig1
before insert on student for each row
begin
if :new.sno<0 then
raise_application_error(-20001,'學號值爲負,不允許插入');
end if;
end;
/
-----------------------------------------------------------------------
crate or replace trigger trig2
before insert on student for each row
begin
if :new.sno<0 then
:new.sno := -:new.sno; -- 賦值
end if;
end;
/
關於建立在視圖上的觸發器 instead of觸發器,其中寫的就是底層對於表的操作,從而實現對視圖的修改。
啓動與禁用觸發器
alter trigger triggername disable;
alter trigger triggername enable;
刪除觸發器
drop trigger triggername
3、觸發器的類型
數據庫啓動觸發器
create table event_table ( event varchar2(30), time date);
create or replace trigger tr_startup
after startup on database
begin
insert into event_table values( ora_sysevent, sysdate);
end;