使用觸發器

          1 觸發器簡介
          ? 1) 觸發事件
          ? 2) 觸發條件
          ? 3) 觸發操作
          ???? . 觸發器代碼的大小不能超過32k,如果使用大量代碼建立觸發器,應該先建立存儲過程,然后再觸發器中使用call語句調用存儲過程。
          ???? . 觸發器中正能含有select ,insert,update 和delete 語句,而不能含有ddl 語句,和事物控制語句。
          2 建立dml 觸發器
          ?1) 觸發時機
          ? before,after 表示在執行dml操作之后觸發器
          ?2)觸發事件
          ? insert ,update 和delete 操作。也可以使用書法事件
          ?3) dml 觸發器是針對特定表進行的 因此必須制定dml 操作所對應的表
          ?4) 觸發器類型 用于指定當觸發器事件之后,需要執行幾次觸發器操作。如果指定語句觸發器類型
          那么會執行一次觸發器代碼:如果指定行觸發器類型,則會在每個被作用行上執行一次觸發器代碼。
          ?5) 觸發條件
          ?用于指定執行行觸發器代碼的條件,只有為ture時,才會執行行觸發器代碼。
          ? 6) 如果使用pl/sql 存儲過程,java 存儲過程,或外部處處過程需要在觸發器操作部分直接使用call
          ? 7) dml 觸發器觸發順序
          ?? (1)dml 觸發器在單行數據上的觸發順序。
          ??? 對于單行數據而言,無論是語句此觸發器,還是行觸發器,觸發器代碼實際只執行一次,并且執行
          順序為before 語句觸發器,before 行觸發器,dml 操作,after 行觸發器,after 語句觸發器
          ?? (2) dml 觸發器在多行數據上的觸發順序
          ??? before 語句觸發器
          ??? before 行觸發器
          ??? after 行觸發器
          ??? before行觸發器
          ??? after 行觸發器
          ??? after語句觸發器
          ?? 語句觸發器只被執行一次,而行觸發器在每個行上都執行一次。
          ? 2) 語句觸發器
          ? 當審計dml 操作,或確保dml操作安全執行時,可以使用語句觸發器
          ? 1 建立before 語句觸發器
          ?? create or replace trigger tr_sec_emp
          ?? before insert or update or delete on emp
          ?? begin
          ???? if to_char(sysdate,'DY','nls_dtate_language=AMERICAN') in ('sat','sun') then
          ???? railse_application_error(-200001,'不能在休息日改變雇員信息');
          ???? end if;
          ?? end;?
          ?? 2 使用條件謂詞
          ?? inserting ,updating ,deleting
          ?? create or replace trigger tr_sec_emp
          ?? before insert or update or delete on emp
          ?? begin
          ???? if to_char(sysdate,'DY','nls_date_language=american')
          ????? in('sat','sun') then
          ???? case
          ?????? when inserting then
          ???????? raise_application('-20001','inserting');
          ?????? when updating then
          ???????? raise_application('-20002','updating');
          ?????? when deleting then
          ???????? raise_application('-20003','deleting');
          ???? end case;
          ??? end if;
          ?? end;
          ?? 3 建立after 語句觸發器
          ??? 為了dml 操作,或者dml 操作后執行匯總運算
          ?? create table aduit_table(
          ???? name varchar2(20),ins int,upd int,del int,
          ???? starttime date,endtime date
          ?? );
          ?? create or replace trigger tr_aduit_emp
          ?? after insert or update or delete emp
          ?? declare
          ???? v_temp int;
          ?? begin
          ???? select count(*) into v_temp from aduit_table
          ?????? where name='emp';
          ???? if v_temp=0 then
          ?????? insert into audit_table values
          ?????? ('emp',0,0,0,sysdate,null);
          ???? end if;
          ???? case
          ?????? when? inserting then
          ???????? update aduit_table set ins=ins+1,endtime=sysdate where name='emp';
          ?????? when updating then
          ???????? update audit_table set upd=upd+1,endtime=sysdate where name='emp';
          ?????? when deleting then
          ???????? update aduit_table set del=del+1,endtime=sysdate where name='emp';
          ?? end;
          ? 3) 行觸發器
          ?? 審計數據變化可以使用行觸發器
          ?? 1 建立不before 行觸發器
          ??? 為了取保數據符合商業邏輯或企業規則,對輸入的數據進行復雜的約束,可以使用before行觸發器
          ???? create or replace trigger tr_emp_sal
          ???? before update of sal on emp
          ???? for each row
          ???? begin
          ?????? if :new.sal<:old.sla then
          ???????? raisse_application_error(-200010,'工資只漲不降');
          ?????? end if;
          ???? end;
          ???? 2) 建立after 行觸發器
          ???? 為了審計dml 操作,可以使用語句觸發器或oracle 系統提供的審計功能,而為了審計數據變化
          ,則應該使用after 行觸發器
          ???? create table audit_emp_change(
          ?????? name varchar2(10),odl number(6,2),
          ?????? newsal number(6,2),time date);
          ??? create or replace trigger tr_sal_change
          ??? after update of sal on emp
          ??? for each row
          ??? declare
          ???? v_temp int;
          ??? begin
          ???? select count(*) into v_temp from audit_emp_change where name=:old.ename;
          ??? if v_temp =0 then
          ????? insert into audit_emp_change
          ??????? values(:old,ename,:old.sal,:new,sal,sysdate);
          ??? else
          ????? update audit_emp_change
          ??????? set oldsal=:old.sal,newsal=:new.sal,time=sysdate where name=:old.ename;?
          ??? end if;

          ??? end;
          ???? )
          ??? 3) 限制行觸發器
          ??? 當使用行觸發器,默認情況下會咱每個被作用行上七星一次觸發器代碼,為了時得再特定條件下執行行觸發器代碼,需要使用when 子句
          ??? create or replace trigger tr_sal_change
          ??? after update of sal on emp
          ??? for each row
          ??? when(old.job='salesman')
          ??? declare
          ?????? v_temp int..
          2 dml 觸發器使用注意事項
          ? 觸發器代碼不能從觸發器所對應的基表中讀取數據
          3 dml 觸發器
          ? 為了保證數據庫滿足特定的商業規則或企業邏輯,可以使用約束,觸發器和子程序。約束性能最好,實現最簡單,所以為售選,如果觸發器不盟實現,可以選擇觸發器。
          ? dml 觸發器可以用于實現數據安全保護,數據審計,數據完整性,參照完整性,數據復制等功能。
          ?1) 控制數據安全
          ? create or replace trigger tr_emp_time
          ? before insert or update or delete on emp
          ? begin
          ??? if to_char(sysdate,'hh24') not between '9' and '17' then
          ????? raise_application_error(-20101,'not work time');
          ???? end if;
          ? end;
          ? 2) 實現數據審計
          ? 使用數據審計只能審計sql 操作,而不會記載數據變化
          ? audit insert,update,delete on emp by access
          ? 3)實現數據完整性
          ? 首選約束 alter table emp add constraint ck_sal check (sal>=800),但是在有些情況下只能使用觸發器來實現數據完整性
          ?? create or replace trigger tr_check sal
          ?? before update of sal on emp
          ?? for each row
          ?? when (new.sla<old.sal or new.sal>1.2* old.sal)
          ?? begin
          ????? raise_application_error(,,,,,,)
          ?? end;
          ? 3) 使用引用完整性
          ? 采用 on delete cascade 可以進行集聯刪除,但是卻不能進行集聯更新。采用觸發器實現集聯更新
          ?? create or replace trigger tr_update
          ?? after update of sal on emp
          ?? for each row
          ?? begin
          ???? update emp set depno=:new.deptno where dentno=:old.deptno;
          ?? end;
          4 建立instead of 觸發器
          ? 對于簡單視圖可以直接進行insert update 和delete 等操作,但是對于復雜視圖不允許進行insert,update 和delete 操作。
          ? 滿足一下條件的為復雜視圖
          ??? 具有操作集合符 union,union all ,intersect,minus
          ??? 具有分組函數 min,max,avg,sum,count
          ??? 具有group by connect 編譯 或start with
          ??? 具有distinct
          ??? 具有連接
          ? 為了在復雜視圖上執行dml 操作,必須要基于instead-of 觸發器,建立instead-of 觸發器后,就可以基于復雜視圖執行insert,update和delete 語句。
          ?? instead of 選項只使用于視圖
          ?? 基于視圖建立觸發器時,不能定義before 和 after
          ?? 在建立視圖時不能指定 with check option
          ?? 當建立instead of 觸發器時,必須指定for each row 選項
          ? 1) 建立復雜視圖dept_emp
          ?? create or replace view dept_emp as
          ?? select a.deptno,a.dname,b,empno,b,ename
          ?? from dept a,emp b
          ?? where a,deptno=b.deptno;
          ? 2) 建立 instead-of 觸發器
          ?? create of replacee trigger tr_instead_of_dept_emp
          ?? instead of insert on dept_emp
          ?? for each row
          ?? declare
          ???? v_temp int;
          ?? beegin
          ????? select count(*) into v_temp from dept where deptno=:new.deptno;
          ????? if v_temp=0 then
          ??????? insert into dept(deptno,dname) values(:new.deptno,:new.dname);
          ????? end if;
          ????? select count(*)into v_temp from emp where empno=:new.empno;
          ????? if v_temp=0 then
          ???????? insert into emp(empno,ename,deptno)
          ?????????? values(:new.deptno,:new.ename,:new.deptno);
          ???????? end if;
          ?? end;
          ??
          ?? 可以對視圖執行insert 操作了
          ??? insert into dept_emp values(50,'admin','1223','mary')
          5 管理觸發器
          ? 1) 顯示觸發器信息
          ??? select trigger_name,status from user_triggers
          ??? where table_name='emp';
          ?? 2)禁止觸發器
          ??? alter trigger tr_check_sal disable;
          ?? 3) 激活觸發器
          ??? alter trigger tr_check_sal enable;
          ?? 4) 禁止或激活表上的所有觸發器
          ??? alter table emp disable all triggers;
          ??? alter table emo eanble all triggers;?
          ?? 5)重新編譯觸發器
          ??? alter trigger tr_check_sal compile;
          ?? 6) 刪除觸發器
          ??? drop trigger tr_check_sal;

          posted on 2006-10-11 14:44 康文 閱讀(1024) 評論(0)  編輯  收藏 所屬分類: 數據庫

          <2006年10月>
          24252627282930
          1234567
          891011121314
          15161718192021
          22232425262728
          2930311234

          導航

          統計

          常用鏈接

          留言簿(1)

          隨筆分類

          隨筆檔案

          文章檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 安多县| 静宁县| 甘肃省| 大丰市| 龙山县| 苗栗市| 永福县| 吉安市| 兴文县| 邯郸县| 内丘县| 沛县| 阳山县| 冷水江市| 子长县| 常德市| 佛山市| 南京市| 特克斯县| 淮南市| 万安县| 凤城市| 东光县| 阳朔县| 辽宁省| 青川县| 莱西市| 阿坝| 确山县| 中西区| 淮滨县| 巴楚县| 梓潼县| 区。| 孙吴县| 孟州市| 余庆县| 基隆市| 乡宁县| 汽车| 张家口市|