假設一個常規表格而不是一個對象表格,你沒有很多選項。你觸發必須是形式的東西
CREATE OR REPLACE TRIGGER trigger_name
AFTER UPDATE ON table_name
FOR EACH ROW
BEGIN
IF(UPDATING('COLUMN1'))
THEN
INSERT INTO log_table(column_name, column_value)
VALUES('COLUMN1', :new.column1);
END IF;
IF(UPDATING('COLUMN2'))
THEN
INSERT INTO log_table(column_name, column_value)
VALUES('COLUMN2', :new.column2);
END IF;
<<repeat for all columns>>
END;
你可以獲取COLUMN1
,COLUMN2
,...從數據字典(USER_TAB_COLS
),而不是COLUMN<<n>>
字符串硬編碼他們,但你還是要硬編碼對:new
僞記錄中列的引用。
你可能會寫一段代碼,通過查詢數據字典生成上述觸發(USER_TAB_COLS
或ALL_TAB_COLS
最有可能的),建設有DDL語句的字符串,然後做一個EXECUTE IMMEDIATE
執行DDL語句。您隨後必須在任何時候將新列添加到任何表以重新創建該列的觸發器時調用此腳本。編寫和調試這種類型的DDL代碼非常繁瑣,但在技術上並不是特別具有挑戰性。但很少有人值得這樣做,因爲有人不可避免地會添加一個新列並忘記重新運行該腳本,或者某人需要修改觸發器以執行一些額外的工作,並且手動更新觸發器比修改和測試生成的腳本更容易觸發器。
但是,更普遍的是,我會質疑以這種方式存儲數據的智慧。在歷史記錄表中爲修改的每一行的每一列存儲一行使得歷史數據非常具有挑戰性。如果有人想知道特定行在特定時間點處於什麼狀態,則必須將歷史表N次加入其中,其中N是該時間點表中的列數。這會非常低效,很快就會讓人們避免嘗試使用歷史數據,因爲他們無法在合理的時間內對其做有用的事情,而不會讓他們失望。使用具有相同的活動表格列的歷史記錄表(在跟蹤日期等方面添加了一些內容)以及在每次更新行時在歷史表中插入一行是比較有效的。這將消耗更多的空間,但它通常更容易使用。
而Oracle有多種方式來審計數據變更 - 您可以使用AUDIT
DML,您可以使用細粒度審計(FGA),您可以使用Workspace Manager,也可以使用Oracle Total Recall。如果您正在尋找比編寫自己的觸發器代碼更大的靈活性,我強烈建議您研究這些本質上更加自動化的其他技術,而不是嘗試開發自己的架構。
對。想知道我每小時收費多少? SO不是免費的編碼服務。你試過什麼了? – 2012-02-14 17:31:41
@Adrian - 在這裏尋找一個小方向...我的問題從來沒有說明我正在尋找任何人爲我寫代碼...... – 2012-02-14 17:36:14
夠公平的。問題在於你的問題聽起來就像我正在閱讀的Spec doc文件。你必須給我們一些東西。你有沒有辦法?你有沒有研究過這是否可能?你研究過RDBMS(oracle)是否已經提供了這個功能嗎? – 2012-02-14 17:39:48