2012-01-10 132 views
5

我想在表格上放置一個觸發器,該表格將所有插入/更新的數據寫入一個附加的日誌文件,以便使用外部工具進行處理。Oracle觸發器將所有插入/更新寫入文件

是否可以實現這一目標?

+1

您可能希望在插入更新觸發器前使用一個日誌表,然後以批處理方式(每晚,不管)進行處理。一定要添加一個「action_date」日期字段(或時間戳),您可以稍後使用該字段根據發生的ins/upd的時間來選擇性地提取數據。 – tbone 2012-01-10 13:08:03

+0

感謝tbone,這將是一個很好的解決方案。但是在不改變應用程序的情況下,我想我需要在表格上添加一個更新觸發器,在該列的後面添加一個額外的「最新更新/更改列」。或者說甲骨文在這個功能的構建? – user85155 2012-01-11 09:30:19

回答

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 Docs:BEFORE行觸發器比AFTER行觸發器稍微高效。使用AFTER行觸發器時,必須爲觸發器讀取受影響的數據塊(邏輯讀取,而非物理讀取),然後再次觸發語句。或者,使用BEFORE行觸發器時,觸發語句和觸發器的數據塊只能讀取一次。 – Ollie 2012-01-10 13:33:25

1

是的,here你有一個update部分的例子。

你只需要做一個類似的insert部分。

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」edict)來避免這種情況,這通常會導致我看到的數據不一致(或更糟糕)。