Oracle 触发器将所有插入/更新写入文件
Posted
技术标签:
【中文标题】Oracle 触发器将所有插入/更新写入文件【英文标题】:Oracle Trigger to write all Insert/Updates to File 【发布时间】:2012-02-06 19:41:10 【问题描述】:我想在一个表上放置一个触发器,它将所有插入/更新的数据写入一个额外的日志文件,以便使用外部工具进行处理。
有办法实现吗?
【问题讨论】:
您可能希望对日志表使用插入前更新触发器,然后以批处理方式提取出来进行处理(每天晚上,无论如何)。请务必添加一个“action_date”日期字段(或时间戳),您以后可以使用它来根据 ins/upd 发生的时间有选择地提取数据。 感谢 tbone,这将是一个很好的解决方案。但是在不更改应用程序的情况下,我认为我需要在表上放置一个更新触发器,并在该列的后期添加一个额外的“最后更新/更改列”。或者有 oracle 的内置功能吗? 【参考方案1】:您需要创建在更改表行后执行的触发器,并使用 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/
希望对你有帮助...
【讨论】:
正如@tbone 评论的那样,您可能需要考虑使用 BEFORE 触发器,因为它们比 AFTER 触发器更有效 - 来自 oracle 文档:BEFORE 行触发器比 AFTER 行触发器更有效。使用 AFTER 行触发器,必须为触发器读取一次受影响的数据块(逻辑读取,而不是物理读取),然后再为触发语句读取一次。或者,对于 BEFORE 行触发器,数据块必须对触发语句和触发器都只读取一次。【参考方案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 活动。一些商店希望通过将触发器替换为业务逻辑规则(“所有应用程序必须更新 modifed_date”法令)来避免这种情况,这通常会导致我所看到的数据不一致(或更糟)。
【讨论】:
【参考方案3】:是的,here 您有一个 update
部分的示例。
您只需要对insert
部分执行类似的操作即可。
【讨论】:
以上是关于Oracle 触发器将所有插入/更新写入文件的主要内容,如果未能解决你的问题,请参考以下文章
如何将一个触发器写入 SQL Server 2008 的所有表