隨筆-314  評論-209  文章-0  trackbacks-0
          是特定事件出現的時候,自動執行的代碼塊。類似于存儲過程,但是用戶不能直接調用他們。
           
          功能:
          1、 允許/限制對表的修改
          2、 自動生成派生列,比如自增字段
          3、 強制數據一致性
          4、 提供審計和日志記錄
          5、 防止無效的事務處理
          6、 啟用復雜的業務邏輯
           
          開始
          create trigger biufer_employees_department_id
                 before insert or update
                        of department_id
                        on employees
                 referencing old as old_value
                                 new as new_value
                 for each row
                 when (new_value.department_id<>80 )
          begin
                 :new_value.commission_pct :=0;
          end;
          /
           
          觸發器的組成部分:
          1、 觸發器名稱
          2、 觸發語句
          3、 觸發器限制
          4、 觸發操作
           
          1、 觸發器名稱
          create trigger biufer_employees_department_id
          命名習慣:
          biufer(before insert update for each row)
          employees 表名
          department_id 列名
           
          2、 觸發語句
          比如:
          表或視圖上的DML語句
          DDL語句
          數據庫關閉或啟動,startup shutdown 等等
          before insert or update
                        of department_id
                        on employees
                 referencing old as old_value
                                 new as new_value
                 for each row
           
          說明:
          1、 無論是否規定了department_id ,對employees表進行insert的時候
          2、 對employees表的department_id列進行update的時候
           
          3、 觸發器限制
          when (new_value.department_id<>80 )
           
          限制不是必須的。此例表示如果列department_id不等于80的時候,觸發器就會執行。
          其中的new_value是代表更新之后的值。
           
          4、 觸發操作
          是觸發器的主體
          begin
                 :new_value.commission_pct :=0;
          end;
           
          主體很簡單,就是將更新后的commission_pct列置為0
           
          觸發:
          insert into employees(employee_id,
          last_name,first_name,hire_date,job_id,email,department_id,salary,commission_pct )
          values( 12345,’Chen’,’Donny’, sysdate, 12, ‘donny@hotmail.com’,60,10000,.25);
           
          select commission_pct from employees where employee_id=12345;
           
          觸發器不會通知用戶,便改變了用戶的輸入值。
           
           
          觸發器類型:
          1、 語句觸發器
          2、 行觸發器
          3、 INSTEAD OF 觸發器
          4、 系統條件觸發器
          5、 用戶事件觸發器
           
           
           
          1、 語句觸發器
          是在表上或者某些情況下的視圖上執行的特定語句或者語句組上的觸發器。能夠與INSERT、UPDATE、DELETE或者組合上進行關聯。但是無論使用什么樣的組合,各個語句觸發器都只會針對指定語句激活一次。比如,無論update多少行,也只會調用一次update語句觸發器。
           
          例子:
          需要對在表上進行DML操作的用戶進行安全檢查,看是否具有合適的特權。
          Create table foo(a number);
           
          Create trigger biud_foo
                 Before insert or update or delete
                        On foo
          Begin
                 If user not in (‘DONNY’) then
                        Raise_application_error(-20001, ‘You don’t have access to modify this table.’);
                 End if;
          End;
          /
           
          即使SYS,SYSTEM用戶也不能修改foo表
           
          [試驗]
          對修改表的時間、人物進行日志記錄。
           
          1、 建立試驗表
          create table employees_copy as select *from hr.employees
           
          2、 建立日志表
          create table employees_log(
                  who varchar2(30),
                  when date);
           
          3、 在employees_copy表上建立語句觸發器,在觸發器中填充employees_log 表。
          Create or replace trigger biud_employee_copy
                        Before insert or update or delete
                               On employees_copy
                 Begin
                        Insert into employees_log(
                               Who,when)
                        Values( user, sysdate);
                       
                 End;
                 /
          4、 測試
          update employees_copy set salary= salary*1.1;
           
          select *from employess_log;
           
          5、 確定是哪個語句起作用?
          即是INSERT/UPDATE/DELETE中的哪一個觸發了觸發器?
          可以在觸發器中使用INSERTING / UPDATING / DELETING 條件謂詞,作判斷:
          begin
                  if inserting then
                         -----
                  elsif updating then
                         -----
                  elsif deleting then
                         ------
                  end if;
          end;
           
          if updating(‘COL1’) or updating(‘COL2’) then
                  ------
          end if;
           
          [試驗]
          1、 修改日志表
          alter table employees_log
                  add (action varchar2(20));
           
          2、 修改觸發器,以便記錄語句類型。
          Create or replace trigger biud_employee_copy
                        Before insert or update or delete
                               On employees_copy
                 Declare
                        L_action employees_log.action%type;
                 Begin
                  if inserting then
                         l_action:=’Insert’;
                  elsif updating then
                         l_action:=’Update’;
                  elsif deleting then
                         l_action:=’Delete’;
                  else
                         raise_application_error(-20001,’You should never ever get this error.’);
           
                        Insert into employees_log(
                               Who,action,when)
                        Values( user, l_action,sysdate);
                 End;
                 /
           
          3、 測試
          insert into employees_copy( employee_id, last_name, email, hire_date, job_id)
                 values(12345,’Chen’,’Donny@hotmail’,sysdate,12);
           
          select *from employees_log
            

          Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1711633

          posted on 2008-05-27 15:22 xzc 閱讀(901) 評論(1)  編輯  收藏 所屬分類: Oracle

          評論:
          # re: Oracle觸發器 2008-05-28 14:49 | xzc
          語法規則:
          Create [or replace] trigger [模式.]觸發器名
          Before| after insert|delete|(update of 列名)

          On 表名

          [for each row]

          When 條件

          PL/SQL塊

          說明:

          For each row的意義是:在一次操作表的語句中,每操作成功一行就會觸發一次;不寫的話,表示是表級觸發器,則無論操作多少行,都只觸發一次;

          When條件的出現說明了,在DML操作的時候也許一定會觸發觸發器,但是觸發器不一定會做實際的工作,比如when 后的條件不為真的時候,觸發器只是簡單地跳過了PL/SQL塊;

          例子:

          sql 代碼
          create or replace trigger wf_tri_user_list before insert or update or delete on user_list
          for each row
          declare
          uid varchar2(10); useq varchar2(10); asql varchar2(200); namea varchar2(200); nameb varchar2(200);
          begin
          namea:=NULL;
          nameb:=NULL;
          if inserting then
          insert into wflow.bpm_org_user(userid,username,diaplayname,seq) values(:NEW.user_id,:NEW.user_name,:NEW.user_realname,:NEW.user_id);
          dbms_output.put_line('insert trigger is chufale .....');

          end if;
          if updating then
          if (:NEW.user_name<>:OLD.user_name) and (:NEW.user_realname<>:OLD.user_realname) then
          namea:=:NEW.user_name;
          nameb:=:NEW.user_realname;
          asql:='update wflow.bpm_org_user set diaplayname=:1 where username=:2';
          execute immediate asql using namea,nameb;
          else
          if :NEW.user_name<>:OLD.user_name then
          namea:=:NEW.user_name;
          asql:='update wflow.bpm_org_user set user_name=:1 where username=:2';
          execute immediate asql using namea;
          else
          if :NEW.user_realname<>:OLD.user_realname then
          nameb:=:NEW.user_realname;
          asql:='update wflow.bpm_org_user set diaplayname=:1 where username=:2';
          execute immediate asql using nameb,:OLD.user_id;
          end if;
          end if;
          end if;
          end if;
          if deleting then
          update wflow.bpm_org_jobusers set userid = 0 where :OLD.user_id =userid and parentid=-1;
          delete from wflow.bpm_org_jobusers where userid = :OLD.user_id;
          delete wflow.bpm_org_user where userid=:OLD.user_id;
          end if;
          commit;
          end;




          關鍵字:

          :NEW 和:OLD使用方法和意義,new 只出現在insert和update時,old只出現在update和delete時。在insert時new表示新插入的行數據,update時new表示要替換的新數據、old表示要被更改的原來的數據行,delete時old表示要被刪除的數據。

          注意:

          在觸發器中不能使用commit。
            回復  更多評論
            
          主站蜘蛛池模板: 余江县| 巧家县| 随州市| 长治县| 新晃| 武川县| 山西省| 和顺县| 喜德县| 北辰区| 台南市| 金秀| 五河县| 翼城县| 高清| 兴安盟| 新晃| 湘潭市| 淄博市| 柏乡县| 留坝县| 茂名市| 永清县| 南木林县| 内乡县| 山阴县| 宝兴县| 垣曲县| 大渡口区| 凯里市| 奈曼旗| 德钦县| 张家川| 嘉定区| 东阿县| 中江县| 依安县| 成安县| 赤城县| 离岛区| 酒泉市|