<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆-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 閱讀(897) 評論(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。
      回復  更多評論
      
    主站蜘蛛池模板: 久久国产免费观看精品| 国内精品一级毛片免费看| 中文字幕第13亚洲另类| 无码人妻精品中文字幕免费| 亚洲色图在线播放| 亚洲精品天堂成人片AV在线播放 | 亚洲黄色片免费看| 久久精品熟女亚洲av麻豆| 亚洲精品无码成人片久久| 特级毛片A级毛片100免费播放| 中文字幕亚洲一区二区三区| 国产精品怡红院永久免费| 特级毛片A级毛片免费播放| 亚洲第一区视频在线观看| 亚洲国产成人久久综合野外| 91高清免费国产自产| 久久精品国产亚洲av麻豆色欲 | 国产午夜亚洲精品午夜鲁丝片| 国产大片线上免费观看| 国产精品hd免费观看| 亚洲中文字幕无码亚洲成A人片| 亚洲精品国产美女久久久| 四色在线精品免费观看| 免费看又黄又无码的网站| 久久精品国产免费观看| 又色又污又黄无遮挡的免费视| 亚洲狠狠婷婷综合久久| 亚洲高清在线播放| 亚洲精品WWW久久久久久| 成人免费福利电影| 免费人成大片在线观看播放电影| 亚洲精品视频专区| 国产l精品国产亚洲区在线观看| 全黄性性激高免费视频| 最近中文字幕mv手机免费高清| 无码人妻丰满熟妇区免费| 丁香花在线观看免费观看图片| 亚洲成A人片在线观看WWW| 亚洲精品永久www忘忧草| 久久久久噜噜噜亚洲熟女综合| 四虎www免费人成|