<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。
      回復  更多評論
      
    主站蜘蛛池模板: 男女拍拍拍免费视频网站| 亚洲区日韩精品中文字幕| 51午夜精品免费视频| vvvv99日韩精品亚洲| 美女又黄又免费的视频| 成年在线网站免费观看无广告| 亚洲AV无码一区二区三区在线| 亚洲三级在线免费观看| 亚洲一卡2卡4卡5卡6卡在线99| 99无码人妻一区二区三区免费| 久久久久精品国产亚洲AV无码| 最新欧洲大片免费在线| 亚洲第一成年免费网站| 四虎免费永久在线播放| 四虎影视久久久免费观看| 国产亚洲精品精品国产亚洲综合| 精品久久久久久无码免费| 久久精品亚洲视频| 中文字幕乱码免费视频| 亚洲精品无码你懂的| 免费在线黄色网址| 免费网站看av片| 国产v亚洲v天堂a无| 又黄又爽无遮挡免费视频| a级成人毛片免费图片| 亚洲视频免费观看| 国产色爽免费视频| a免费毛片在线播放| 久久综合亚洲色一区二区三区| 中文字幕无码成人免费视频| 水蜜桃视频在线观看免费| 亚洲av中文无码乱人伦在线咪咕| 永久在线免费观看| 黄色片网站在线免费观看| 亚洲AV无码久久精品色欲| 成人人免费夜夜视频观看| 999zyz**站免费毛片| 国产亚洲中文日本不卡二区| 黑人大战亚洲人精品一区| 大学生一级毛片免费看| selaoban在线视频免费精品|