關于觸發器修改自身數據表實例
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;