關于觸發器修改自身數據表實例
2024-07-21 02:37:56
供稿:網友
 
             
  1 前言 
  當然,在觸發器修改自身數據表,對于有Oracle數據庫后臺編程人員來說,并不應該算是一個難題,可能在平時的工作中就經常要碰到。 
  但對于剛剛使用ORACLE數據庫后臺編程人員來說,的確是一個比較煩人的問題。 
  
                                                                                              2 說明 
  ORACLE的觸發器分為兩類:行觸發器(For Each Row)和表觸發器,在行觸發器中,不得將Insert/Update/Delete語句作用于自身數據表;在表觸發器中,不得使用:New/:Old語句。 
  但在實際編程過程中,我們往往需要對自身數據表進行DML(Insert/Update/Delete)操作,同時引用:New/:Old對象。 
  如:使用Insert Into xxx (Select * From yyy Where xKey=123456)語句后,我們需要保存插入記錄的時間,由于數據庫操作的時間差,我們不可以使用:New.xDate:=SysDate語句<使用這一語句后,插入的每筆記錄xDate的數值會不一樣,可相差數秒>。 
  對我們來說,最好的語句是:Update xxx Set xDate=SysDate Where xKey=:New.xKey。此時,我們使用Update語句的同時,又使用了:New對象,ORACLE認為不合法。 
  
  3 解決提案
  實現此需求,我們需要建立一個行觸發器、一個表觸發器以及一個程序包。 
  
  --3.0 創建測試環境 
  Drop Table xxx; 
  Drop Table yyy; 
  --創建數據表 
  Create Table xxx( 
    xKey  Number(4), 
    xDate  Date, 
    xData  number(10)); 
  Create Table yyy( 
    xKey  Number(4), 
    xDate  Date, 
    xData  number(10)); 
  
  --3.1 創建程序包,設立全局變量G_xKe 
  Create Or Replace Package Pkg_xxx_Update 
  as 
    G_xKey xxx.xKey%Type; 
  End Pkg_xxx_Update; 
  / 
  --3.2 創建行觸發器,并將xKey的值存入程序包的全局變量中 
  Create Or Replace Trigger TRG_Upd_xxx_Rec 
  After Insert On xxx 
  For Each Row 
  Begin 
    Pkg_xxx_update.G_xKey:=:New.xKey; 
  End; 
  / 
  --3.3 創建表觸發器,根據程序包的全局變量,對數據表的xDate字段進行更新 
  Create Or Replace Trigger TRG_Upd_xxx_TB 
  After Insert On xxx 
  Begin 
    Update xxx 
     set 
       xDate=SysDate 
     Where 
       xKey=PKG_xxx_Update.G_xKey; 
  End; 
  / 
  --3.4 插入大量數據 
  <<InsertMultiRecord>> 
  Declare 
  L_Count Number:=1; 
  Begin 
  Delete from yyy; 
  While L_Count<100000 
  Loop 
  insert into yyy 
  values(1, SysDate, L_Count); 
  L_Count:=L_Count+1; 
  End Loop; 
  Commit; 
  End InsertMultiRecord; 
  
  --3.5 測試觸發器 
  Insert Into xxx 
    (Select * from yyy); 
  Commit; 
  Select * From xxx;