前言
当然在触发器修改自身数据表对于有ORACLE数据库后台编程人员来说并不应该算是一个难题可能在平时的工作中就经常要遇到
但对于刚刚使用ORACLE数据库后台编程人员来说的确是一个比较烦人的问题
说明
ORACLE的触发器分为两类行触发器(For Each Row)和表触发器在行触发器中不得将Insert/Update/Delete语句作用于自身数据表在表触发器中不得使用:New/:Old语句
但在实际编程过程中我们往往需要对自身数据表进行DML(Insert/Update/Delete)操作同时引用:New/:Old对象
如使用Insert Into xxx (Select * From yyy Where xKey=)语句后我们需要保存插入记录的时间由于数据库操作的时间差我们不可以使用:NewxDate:=SysDate语句<使用这一语句后插入的每笔记录xDate的数值会不一样可相差数秒>
对我们来说最好的语句是Update xxx Set xDate=SysDate Where xKey=:NewxKey此时我们使用Update语句的同时又使用了:New对象ORACLE认为不合法
解决提案
实现此需求我们需要建立一个行触发器一个表触发器以及一个程序包
创建测试环境
Drop Table xxx;
Drop Table yyy;
创建数据表
Create Table xxx(
xKey Number()
xDate Date
xData number());
Create Table yyy(
xKey Number()
xDate Date
xData number());
创建程序包设立全局变量G_xKe
Create Or Replace Package Pkg_xxx_Update
as
G_xKey xxxxKey%Type;
End Pkg_xxx_Update;
/
创建行触发器并将xKey的值存入程序包的全局变量中
Create Or Replace Trigger TRG_Upd_xxx_Rec
After Insert On xxx
For Each Row
Begin
Pkg_xxx_updateG_xKey:=:NewxKey;
End;
/
创建表触发器根据程序包的全局变量对数据表的xDate字段进行更新
Create Or Replace Trigger TRG_Upd_xxx_TB
After Insert On xxx
Begin
Update xxx
set
xDate=SysDate
Where
xKey=PKG_xxx_UpdateG_xKey;
End;
/
插入大量数据
<<InsertMultiRecord>>
Declare
L_Count Number:=;
Begin
Delete from yyy;
While L_Count<
Loop
insert into yyy
values( SysDate L_Count);
L_Count:=L_Count+;
End Loop;
Commit;
End InsertMultiRecord;
测试触发器
Insert Into xxx
(Select * from yyy);
Commit;
Select * From xxx;