使用觸發(fā)器

          1 觸發(fā)器簡(jiǎn)介
          ? 1) 觸發(fā)事件
          ? 2) 觸發(fā)條件
          ? 3) 觸發(fā)操作
          ???? . 觸發(fā)器代碼的大小不能超過(guò)32k,如果使用大量代碼建立觸發(fā)器,應(yīng)該先建立存儲(chǔ)過(guò)程,然后再觸發(fā)器中使用call語(yǔ)句調(diào)用存儲(chǔ)過(guò)程。
          ???? . 觸發(fā)器中正能含有select ,insert,update 和delete 語(yǔ)句,而不能含有ddl 語(yǔ)句,和事物控制語(yǔ)句。
          2 建立dml 觸發(fā)器
          ?1) 觸發(fā)時(shí)機(jī)
          ? before,after 表示在執(zhí)行dml操作之后觸發(fā)器
          ?2)觸發(fā)事件
          ? insert ,update 和delete 操作。也可以使用書(shū)法事件
          ?3) dml 觸發(fā)器是針對(duì)特定表進(jìn)行的 因此必須制定dml 操作所對(duì)應(yīng)的表
          ?4) 觸發(fā)器類(lèi)型 用于指定當(dāng)觸發(fā)器事件之后,需要執(zhí)行幾次觸發(fā)器操作。如果指定語(yǔ)句觸發(fā)器類(lèi)型
          那么會(huì)執(zhí)行一次觸發(fā)器代碼:如果指定行觸發(fā)器類(lèi)型,則會(huì)在每個(gè)被作用行上執(zhí)行一次觸發(fā)器代碼。
          ?5) 觸發(fā)條件
          ?用于指定執(zhí)行行觸發(fā)器代碼的條件,只有為ture時(shí),才會(huì)執(zhí)行行觸發(fā)器代碼。
          ? 6) 如果使用pl/sql 存儲(chǔ)過(guò)程,java 存儲(chǔ)過(guò)程,或外部處處過(guò)程需要在觸發(fā)器操作部分直接使用call
          ? 7) dml 觸發(fā)器觸發(fā)順序
          ?? (1)dml 觸發(fā)器在單行數(shù)據(jù)上的觸發(fā)順序。
          ??? 對(duì)于單行數(shù)據(jù)而言,無(wú)論是語(yǔ)句此觸發(fā)器,還是行觸發(fā)器,觸發(fā)器代碼實(shí)際只執(zhí)行一次,并且執(zhí)行
          順序?yàn)閎efore 語(yǔ)句觸發(fā)器,before 行觸發(fā)器,dml 操作,after 行觸發(fā)器,after 語(yǔ)句觸發(fā)器
          ?? (2) dml 觸發(fā)器在多行數(shù)據(jù)上的觸發(fā)順序
          ??? before 語(yǔ)句觸發(fā)器
          ??? before 行觸發(fā)器
          ??? after 行觸發(fā)器
          ??? before行觸發(fā)器
          ??? after 行觸發(fā)器
          ??? after語(yǔ)句觸發(fā)器
          ?? 語(yǔ)句觸發(fā)器只被執(zhí)行一次,而行觸發(fā)器在每個(gè)行上都執(zhí)行一次。
          ? 2) 語(yǔ)句觸發(fā)器
          ? 當(dāng)審計(jì)dml 操作,或確保dml操作安全執(zhí)行時(shí),可以使用語(yǔ)句觸發(fā)器
          ? 1 建立before 語(yǔ)句觸發(fā)器
          ?? 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 語(yǔ)句觸發(fā)器
          ??? 為了dml 操作,或者dml 操作后執(zhí)行匯總運(yùn)算
          ?? 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) 行觸發(fā)器
          ?? 審計(jì)數(shù)據(jù)變化可以使用行觸發(fā)器
          ?? 1 建立不before 行觸發(fā)器
          ??? 為了取保數(shù)據(jù)符合商業(yè)邏輯或企業(yè)規(guī)則,對(duì)輸入的數(shù)據(jù)進(jìn)行復(fù)雜的約束,可以使用before行觸發(fā)器
          ???? 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 行觸發(fā)器
          ???? 為了審計(jì)dml 操作,可以使用語(yǔ)句觸發(fā)器或oracle 系統(tǒng)提供的審計(jì)功能,而為了審計(jì)數(shù)據(jù)變化
          ,則應(yīng)該使用after 行觸發(fā)器
          ???? 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) 限制行觸發(fā)器
          ??? 當(dāng)使用行觸發(fā)器,默認(rèn)情況下會(huì)咱每個(gè)被作用行上七星一次觸發(fā)器代碼,為了時(shí)得再特定條件下執(zhí)行行觸發(fā)器代碼,需要使用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 觸發(fā)器使用注意事項(xiàng)
          ? 觸發(fā)器代碼不能從觸發(fā)器所對(duì)應(yīng)的基表中讀取數(shù)據(jù)
          3 dml 觸發(fā)器
          ? 為了保證數(shù)據(jù)庫(kù)滿(mǎn)足特定的商業(yè)規(guī)則或企業(yè)邏輯,可以使用約束,觸發(fā)器和子程序。約束性能最好,實(shí)現(xiàn)最簡(jiǎn)單,所以為售選,如果觸發(fā)器不盟實(shí)現(xiàn),可以選擇觸發(fā)器。
          ? dml 觸發(fā)器可以用于實(shí)現(xiàn)數(shù)據(jù)安全保護(hù),數(shù)據(jù)審計(jì),數(shù)據(jù)完整性,參照完整性,數(shù)據(jù)復(fù)制等功能。
          ?1) 控制數(shù)據(jù)安全
          ? 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) 實(shí)現(xiàn)數(shù)據(jù)審計(jì)
          ? 使用數(shù)據(jù)審計(jì)只能審計(jì)sql 操作,而不會(huì)記載數(shù)據(jù)變化
          ? audit insert,update,delete on emp by access
          ? 3)實(shí)現(xiàn)數(shù)據(jù)完整性
          ? 首選約束 alter table emp add constraint ck_sal check (sal>=800),但是在有些情況下只能使用觸發(fā)器來(lái)實(shí)現(xiàn)數(shù)據(jù)完整性
          ?? 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 可以進(jìn)行集聯(lián)刪除,但是卻不能進(jìn)行集聯(lián)更新。采用觸發(fā)器實(shí)現(xiàn)集聯(lián)更新
          ?? 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 觸發(fā)器
          ? 對(duì)于簡(jiǎn)單視圖可以直接進(jìn)行insert update 和delete 等操作,但是對(duì)于復(fù)雜視圖不允許進(jìn)行insert,update 和delete 操作。
          ? 滿(mǎn)足一下條件的為復(fù)雜視圖
          ??? 具有操作集合符 union,union all ,intersect,minus
          ??? 具有分組函數(shù) min,max,avg,sum,count
          ??? 具有g(shù)roup by connect 編譯 或start with
          ??? 具有distinct
          ??? 具有連接
          ? 為了在復(fù)雜視圖上執(zhí)行dml 操作,必須要基于instead-of 觸發(fā)器,建立instead-of 觸發(fā)器后,就可以基于復(fù)雜視圖執(zhí)行insert,update和delete 語(yǔ)句。
          ?? instead of 選項(xiàng)只使用于視圖
          ?? 基于視圖建立觸發(fā)器時(shí),不能定義before 和 after
          ?? 在建立視圖時(shí)不能指定 with check option
          ?? 當(dāng)建立instead of 觸發(fā)器時(shí),必須指定for each row 選項(xiàng)
          ? 1) 建立復(fù)雜視圖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 觸發(fā)器
          ?? 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;
          ??
          ?? 可以對(duì)視圖執(zhí)行insert 操作了
          ??? insert into dept_emp values(50,'admin','1223','mary')
          5 管理觸發(fā)器
          ? 1) 顯示觸發(fā)器信息
          ??? select trigger_name,status from user_triggers
          ??? where table_name='emp';
          ?? 2)禁止觸發(fā)器
          ??? alter trigger tr_check_sal disable;
          ?? 3) 激活觸發(fā)器
          ??? alter trigger tr_check_sal enable;
          ?? 4) 禁止或激活表上的所有觸發(fā)器
          ??? alter table emp disable all triggers;
          ??? alter table emo eanble all triggers;?
          ?? 5)重新編譯觸發(fā)器
          ??? alter trigger tr_check_sal compile;
          ?? 6) 刪除觸發(fā)器
          ??? drop trigger tr_check_sal;

          posted on 2006-10-11 14:44 康文 閱讀(1024) 評(píng)論(0)  編輯  收藏 所屬分類(lèi): 數(shù)據(jù)庫(kù)

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

          導(dǎo)航

          統(tǒng)計(jì)

          常用鏈接

          留言簿(1)

          隨筆分類(lèi)

          隨筆檔案

          文章檔案

          搜索

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 武功县| 甘泉县| 曲松县| 烟台市| 崇仁县| 房山区| 禹城市| 鸡泽县| 芦溪县| 开远市| 康平县| 荆州市| 璧山县| 台中市| 河北省| 靖宇县| 南康市| 五大连池市| 墨玉县| 青河县| 红河县| 邵阳县| 绥宁县| 文水县| 祁连县| 宁明县| 江西省| 临潭县| 会宁县| 丘北县| 青阳县| 台南市| 安乡县| 阿克苏市| 亳州市| 堆龙德庆县| 望奎县| 靖安县| 特克斯县| 厦门市| 鹤山市|