Oracle触发器:将所有插入/更新操作写入文件

7
我希望在表上放置触发器,将所有插入/更新的数据写入一个额外的日志文件中,以便使用外部工具进行处理。是否有实现此目标的方法?

1
你可能想要使用一个before insert update触发器来记录到一个日志表中,然后稍后批量处理(每晚或其他时间)。请确保添加一个"action_date"日期字段(或时间戳),以便您可以根据插入/更新发生的时间有选择地提取数据。 - tbone
谢谢Tbone,这将是一个不错的解决方案。但是不更改应用程序,我认为我需要在表上放置一个更新触发器,并添加一个额外的“最后更新/更改列”,然后在该列上进行延迟选择。或者Oracle有内置功能来实现此操作吗? - user85155
3个回答

5
您需要创建触发器,以在表行被更改后执行并使用UTL_FILE包写入日志文件。
UTL_FILE包信息可在此处找到: http://docs.oracle.com/cd/B19306_01/appdev.102/b14258/u_file.htm 触发器文档可在此处找到: http://docs.oracle.com/cd/B10501_01/appdev.920/a96590/adg13trg.htm 这里有一个类似的答案,适用于您所寻找的内容: http://bytes.com/topic/oracle/answers/762007-trigger-output-text-file 有关使用PL / SQL写入文件的更多信息,请参见此处: http://www.devshed.com/c/a/Oracle/Writing-to-Text-Files-in-Oracle-PLSQL/ 希望对您有所帮助...

1
正如@tbone所评论的那样,您可能需要考虑使用BEFORE触发器,因为它们比AFTER触发器更有效 - 来自Oracle文档:BEFORE行触发器比AFTER行触发器稍微更有效。对于AFTER行触发器,受影响的数据块必须被读取(逻辑读取,而不是物理读取)一次用于触发器,然后再为触发语句读取一次。或者,对于BEFORE行触发器,数据块只需为触发语句和触发器读取一次。 - Ollie

2

我建议避免在DML时间写入文件系统,而应该每天(或其他频率)批量处理数据并将其提取出来。

从您的OP中,不清楚您是否需要更新后的“新”数据还是更新前的“旧”数据。如果您只需要最新数据,为什么不添加一个modified_date字段(日期或时间戳类型),并通过触发器进行更新。

create table test
(
id number,
val varchar2(100),
modified_date date  default sysdate not null
)
;

CREATE OR REPLACE TRIGGER TR_TEST_BU
BEFORE UPDATE
ON TEST REFERENCING NEW AS NEW OLD AS OLD
FOR EACH ROW
begin
  :new.modified_date := sysdate;
end;

insert into test(id, val) values (1, 'Insert 1');
commit;

select * from test;

exec dbms_lock.sleep(5);
update test set val = 'Update 1' where id = 1;
commit;

select * from test;

如果您需要更新前的旧数据(或者关心已删除的数据),那么您需要修改触发器,将旧值或已删除的值写入历史表,然后从那里提取数据。
还要注意,向表添加触发器会减慢相关的DML操作。一些商家希望通过用业务逻辑规则替换触发器("所有应用程序必须更新modified_date"法令)来避免这种情况,但我看到这通常会导致不一致的数据(或更糟糕)。

1

是的,这里有一个update部分的示例。

你只需要做一个类似于insert部分的即可。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接