Junky's IT Notebook

          導航

          <2007年6月>
          272829303112
          3456789
          10111213141516
          17181920212223
          24252627282930
          1234567

          隨筆分類(224)

          文章分類(5)

          隨筆檔案(228)

          文章檔案(7)

          統計

          留言簿(8)

          積分與排名

          WebSphere Studio

          閱讀排行榜

          評論排行榜

          Oracle觸發器


          觸發器的概念和類型
            數據庫觸發器(database triggers)是響應插入、更新或刪除等數據庫事件而執行的過程。它定義了當一些數據庫相關事件發生時應采取的動作。可用于管理復雜的完整性約束,或監控對表的修改,或通知其它程序,表已發生修改。它的類型有:語句級觸發器,以及行級觸發器,前者可以在語句執行前或執行后被觸發。后者在每個觸發語句影響的行觸發一次。還有before和after觸發的命令。在insert,update,和delete之前或之后執行,引用新舊值進行處理。如果需通過觸發器設定插入行中的某列值,則為了訪問“新(new)”值,需使用一個觸發器before insert,使用after insert則不行。Instead of 觸發器命令,使用它告訴oracle應執行什么操作。以上四種大類合成14種小類(略)。各種觸發器的執行順序如下:
            ⑴   如果有,最先執行語句級before觸發器。
            ⑵   每個insert,delete,update影響的行;
             ①  如果有,最先執行行級before
             ②  執行行的delete或update
             ③  如果有,執行行級after觸發器
            ⑶   如果有,執行語句級after觸發器
            
            1、使用數據庫觸發器管理數據冗余性
            為了數據分析和制作報表的需要,用戶在數據模型中加入了冗余數據,應使用觸發器,以保證數據的完整性。
            冗余數據可以用規定的 for each row選項的before update觸發器進行管理。update 命令可放在觸發器中對所有需要更新的冗余數據進行更新,如客戶表和訂單表,訂單表包括客戶的訂單和客戶表的冗余信息,客戶表(customer)的表結構:客戶號(cu_no)、客戶名(cu_name)、客戶地址(cu_address)。訂單表(order)的表結構:訂單號(or_no),客戶號(or_no),客戶名(cu_name),客戶地址(cu_address),當客戶基表中的數據被更新時更新訂單中的冗余列。語法如下:

           create or replace trigger bj_customer
           before update on customer
           for each row
           begin
            update order set
            cu_no=:new.cu_no,
            cu_name=:new.cu_name,
            cu_address=:new.cu_addess,
            where cu_no=:old.cu_no;
           end;
            
            2、用觸發器完成數據復制
            如果需求非常有限,可以用數據觸發器從一個數據庫中向另一個數據庫復制數據,如果數據復制需求僅與數據的插入有關,當一條記錄插入到一個數據庫中的某個基表中時,用戶還希望把這條記錄插入到一個遠程數據庫中,需用create database link語句創建一條到遠程數據庫的連接,一旦創建了一條數據庫連接后,就可以在基表上創建一個after insert觸發器,以把每一條記錄插入到遠程數據庫中。
            
            (1)在腳本中創建數據庫連接(database link)bj_ysd_remote基表作為數據庫基表,Bj_ysd_local代表本地數據庫上的源基表。
            
           Creat database link remote(連接名)
           Connect to bj(帳戶) indentified by bj(密碼)
           Using ':2';
            
            (2)復制記錄
            
           create or replace trigger trig_ysd
           after insert on bj_ysd_local
           for each row
           begin
            insert into bj_ysd_remote@dblink remote
            value(:new.x1,:new.x2,……)/*x1.x2代表字段名*/
           end;
            
            (3)刪除記錄
            
           create or replace trigger trig_ysd_del
           after delete on bj_ysd_local
           for each row
           begin
            delete from bj_ysd_remote@dblink remote
            where x1=:old.x1
           end;
            
            3、用數據庫觸發器完成瀑布式刪除操作
            在某些情況下,當要刪除一條記錄時,該記錄是與外鍵有關的另外一張基表上的記錄時,這個刪除操作必須在模型中進行傳遞,否則會出現大量的冗長數據,仍以cumstomer 和order基表為例,當從customer中刪除一個客戶時,order基表中所有相關記錄也應當刪除。

           Create or replace trigger trig_cust
           Before delete on customer
           For each row
           Begin
            Delete from order
            Where cu_no=old.cu_no;
           End;
            
            4、用觸發器完成動態數據的操作
            在涉及如何實現動態庫存的問題時,可用觸發器解決。倉庫有驗收、出庫、調撥、報廢、退料、讓售等這些數據必須與以前的庫存相加減,才能完成動態庫存操作。本文僅以驗收單觸發器為例,其它的結構雷同。它們涉及到兩個基表:bi­_ysd(驗收單),Bj_kcb(當前庫存表),前者的表結構(rq(日期),ysdh(驗收單號), bjbm(備件編碼),yssl(驗收數量),ysdj(驗收單價)),后者的表結構為(bjbm(備件編碼),dqkcl(當前庫存量),dqkcje(當前庫存金額))觸發器如下:
            
           create or replace trigger trig_ysd
           after insert or update or delete on bj_ysd
           for each row
            declare rq1 varchar2(8);rq2 varchar2(8);
            /*限于篇幅,yssl1,yssl2,ysdj1,ysdj2,bjbm1,bjbm2,ii聲明略*/
            if inserting or updating then
             rq1:=:new.rq;bjbm1:=:new.bjbm;yssl1:=:new.yssl;
             ysdj1:=:new.ysdj;
            
             select count(*) into ii from bj_dqkcb
             where bjbm=bjbm1;
            
             if ii=0 then
              insert into bj_dqkcb(bjbm,dqkcl,dqkcje)
              value(bjbm1,yssl1,ysdj1);
             else
              update bj_dqkcb
              set dqkcl=dqkcl+yssl1;
                 dqkcje=dqkcje+yssl1*ysdj1;
             end if
            end if
            
            if deleting or updating then
             rq2:=:old.rq;
             bjbm2:=:old.bjbm;
             yssl2:=:old.yssl;
             ysdj2:=:old.ysdj;
             update bj_dqkcb
             set dqkcb=dqkcl-yssl2;
              dqkcje=dqkcje-yssl2*ysdj2
            end if;
           end ;
            
            5、結束語
            數據庫觸發器在數據庫開發有很廣泛的應用,但經驗表明,使用過多的觸發器將降低整個數據庫的性能。如果數據庫觸發器寫得不好,它會很快破壞數據庫的性能,因此,在適當的時候使用恰當的觸發器顯得非常重要。

          posted on 2007-06-19 09:37 junky 閱讀(375) 評論(0)  編輯  收藏 所屬分類: Oracle


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 孙吴县| 广宁县| 嵊州市| 南华县| 康平县| 望奎县| 澄迈县| 宁德市| 伊金霍洛旗| 漯河市| 张北县| 湘潭县| 北川| 扎囊县| 额济纳旗| 万安县| 顺义区| 长兴县| 新干县| 柳州市| 灵山县| 衡阳县| 上高县| 崇义县| 来凤县| 湘潭市| 杭锦后旗| 绥阳县| 利津县| 新乡市| 新民市| 临城县| 张家界市| 乳山市| 沧源| 天等县| 古浪县| 荣昌县| 务川| 巴林左旗| 淅川县|