假设一个常规表格而不是一个对象表格,你没有很多选项。你触发必须是形式的东西
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