觸發器 trigger

觸發器是被指定關聯到一個表的數據對象,它不須要調用,當對一個表的特別事件出現時,它就被激活。觸發器的代碼也是由SQL語句組成的,所以用在存儲過程當中的語句也能夠用再觸發器的定義中。觸發器是一類特殊的存儲過程,與表的關係密切,用於保護表中的數據,當有操做影響到觸發器保護的數據時,觸發器將自動執行。數據庫

(1)DML觸發器:當數據庫中發生數據操做語句(DML)事件時調用DML觸發器。DML事件包括用表或視圖的 insert語句,update語句和delect語句,所以DML觸發器可分爲3種。服務器

(2)代替觸發器:因爲oracle中不能直接對兩個以上的表創建的視圖進行操做,因此給出了代替觸發器。它是oracle專門爲進行視圖操做的一種處理方式。oracle

3)系統觸發器:系統觸發器也由相應的事件觸發,但它的激活通常基於對數據庫系統所進行得操做,如數據定義語句(DDL),啓動或關閉觸發器,鏈接或斷開,服務器錯誤等系統事件。函數

命令建立觸發器:spa

--語法格式
create  or replace trigger 觸發器的名稱
before  /after/instead of
insert/update/delete  
on  for each row

說明:日誌

觸發器名稱:觸發器的名字與過程名和包的名字不同,它有單獨的名字空間,所以觸發器名能夠和表名或過程名同名,但在同一個方案中的觸發器名不能相同。code

after:觸發器在指定操縱都成功執行後觸發,如after insert 表示在向表中插入數據後激活觸發器對象

before:觸發器在指定操做執行前觸發,如before insert 表示在向表中插入數據前激活觸發器blog

instead of: 指定建立代替觸發器,觸發器指定的事件不執行,而執行觸發器自己的操做。事件

delete,insert,update:指定一個或多個觸發器,多個觸發器事件之間用 or 鏈接

of:指定在某列上update觸發器,若是爲多列,則須要使用逗號分隔。

for each row:在觸發器定義中,若是未使用for each row 子句則表示觸發器爲語句觸發器,觸發器在激活後只執行一次,而無論這一操做將影響多行。

 

建立觸發器有如下限制:

(1) 代碼大小。觸發器代碼大小必須小於32K。

(2) 觸發器中有效語句能夠包括DML語句,但不能包括DDL語句。ROLLBACK、COMMIT、SAVEPOINT也不能使用。可是,對於系統觸發器(system trigger)可使用CREATE、ALTER、DROP TABLE和ALTER…COMPILE語句。

(3) LONG、LONG RAW和LOB的限制:

     ① 不能插入數據到LONG或LONG RAW;

     ② 來自LONG或LONG RAW的數據能夠轉換成字符型(如char、varchar2),可是不能超過32K;

     ③ 使用LONG或LONG RAW不能聲明變量;

     ④ 在LONG或LONG RAW列中不能使用:NEW和:PARENT;

     ⑤ 在LOB中的:NEW變量不能修改。

(4) 引用包變量的限制。若是UPDATE或DELETE語句檢測到當前的UPDATE衝突,則Oracle執行ROLLBACK到SAVEPOINT上並從新啓動更新,這樣可能須要屢次才能成功。

 

建立DML觸發器:

--假設數據庫中增長一新表school_students_old,表結構和表school_students相同,用來存放從school_students表
--中刪除的記錄。建立一個觸發器,當school_students表被刪除一行,把刪除的記錄寫到日誌表school_students_old中。
create table school_students_old2 //建立新表 ( STU_ID NVARCHAR2(
20) NOT NULL, STU_NAME NVARCHAR2(20) NOT NULL , STU_SEX NVARCHAR2(20) , STU_CREDITS NUMBER(2) , STU_BIRTHDAY DATE , STU_CLASS NVARCHAR2(20) ); select * from school_students_old2; create or replace trigger delete_stu //建立觸發器 before delete on school_students for each row begin insert into school_students_old2 (STU_ID,STU_NAME,STU_SEX,STU_CREDITS,STU_BIRTHDAY,STU_CLASS) values (:old.STU_ID,:old.STU_NAME,:old.STU_SEX,:old.STU_CREDITS,:old.STU_BIRTHDAY,:old.STU_CLASS); end delete_stu; select * from school_students; select * from school_students_old;

 

建立代替觸發器:

--在數據庫中建立視圖和觸發器,以說明替代觸發器。
create or replace view stu_avg
as
select
RESULT_STU,
avg(result_number) as stu_avg from
SCHOOL_RESULT
group by RESULT_STU;

select * from stu_avg where RESULT_STU='201632218031';

delete from stu_avg where RESULT_STU='201632218031';

create or replace trigger tr_stu_avg_delete
instead of delete on stu_avg for each row
begin
   delete from SCHOOL_RESULT 
   where result_stu=:old.result_stu;
end tr_stu_avg_delete;

 

建立系統觸發器:

--建立當一個用戶userA登陸時自動記錄一些信息的觸發器。
create table login_log
(
   v_user  varchar2(100),
   v_date  date
);

create or replace trigger tr_login_log
  after logon on schema
  declare 
   v_name VARCHAR2(20);
   begin
   select user into v_name from dual;
   insert into login_log values(v_name,sysdate);
   end tr_login_log;
  
  select * from login_log;
  

 

啓用和禁用觸發器:

在oracle中,與過程,函數,包不一樣,觸發器是能夠被禁用和啓用的,在有大量數據要導入數據庫中時,爲了不觸發相應的觸發器以節省處理時間,能夠禁用觸發器,使其暫時失效,觸發器被禁用後任然存儲在數據庫中,只要從新啓用既可使它從新工做。

oracle提供了alter trigger語句來禁用和啓用觸發器

--語法格式
alter trigger [<用戶名方案名.>]<觸發器>
    disable|enable;

其中:disable表示禁用觸發器,enable表示啓用觸發器

 

觸發器的刪除:

--語法格式
drop trigger [<用戶名方案名.>]<觸發器>

也能夠用界面刪除觸發器

相關文章
相關標籤/搜索