问题描述
||
我正在做一个LogTable,在其中保存在RealTable上修改过的数据。
通过数据,我的意思是我需要恢复整个记录的
:new
和:old
值。因此,我有一个触发器,该触发器会响应是否有插入,删除或更新。
所以我的问题是:我怎么知道哪个记录已更改以及如何恢复它的内容?
例:
create table t1(
a integer,b integer
)
create table LogT1(
new_a integer,old_a integer,new_b integer,old_b integer
)
假设t1上有一条记录,其值a = 1,b = 2,t1得到更新,因此记录将值更改为a = 3,b = 4
为了使更新激活触发器,它必须:
知道哪个记录被修改。
恢复该记录。
获取“ b”值和“ before”和“ after”
将这些值分别作为old_a,new_a,old_b,new_b插入LogT1
结果作为在LogT1上的插入,其值为new_a = 3,old_a = 1,new_b = 4,old_b = 2
CREATE or REPLACE TRIGGER tr001
AFTER INSERT OR UPDATE OR DELETE ON t1
DECLARE
a integer;
b integer;
a2 integer;
b2 integer;
BEGIN
IF DELETING THEN
*Recover the row that changed*
*Then use that row*
a2:= :new.a ;
b2:= :new.b ;
a:= :old.a ;
b:= :old.b ;
insert into LogT1 (new_a integer,old_b integer)
values (a2,a,b2,b);
END IF;
....
END tr001;
我对此很陌生,因此,如果我的问题不正确,请向我致以最诚挚的歉意。
解决方法
据我所知,您可能将触发器声明为
FOR EACH ROW
,以便针对删除|插入|更新的每一行都触发该触发器,然后:new和:old包含特定的行值。希望这可以帮助。
CREATE or REPLACE TRIGGER tr001
AFTER INSERT OR UPDATE OR DELETE
ON t1
FOR EACH ROW
DECLARE
...
, 如果您有11克,则可以使用闪回数据存档来执行此操作,
, 这是我在项目中使用的一些PL / SQL,几乎可以完成您想要的全部操作。
我简化了我的脚本(它正在执行其他一些功能):
create or replace trigger rtt.course_log
after insert or update or delete
on rtt.TRAINING_COURSE
for each row
declare msg varchar2(255);
begin
if updating then
msg := \'updating course: \' || :new.name || \'at: \' || :new.updated_at;
elsif inserting then
msg := \'creating course: \' || :new.name || \'at: \' || :new.updated_at;
elsif deleting then
msg := \'deleting course: \' || :new.name || \'at: \' || :new.updated_at;
end if;
insert into rtt.TRAINING_LOG (message,created_at) values (msg,SYSDATE);
end;
, 实际上,如果知道所需数据的时间,则可以恢复旧数据,而无需使用以下查询来创建日志表。它可能满足您的要求。
SELECT * FROM TABLE_NAME AS OF TIMESTAMP
(提供时间戳记所需的时间)