当表中的 任何 列更新时,我想在历史表中插入一行。
我只是想捕获列名,旧值和新值。
我希望此触发器尽可能重用,因为我将在其他表上使用相同的概念。
我熟悉触发器以及如何捕获某一列上的更新。我特别在寻找如何编写 一个 触发器,以将一条记录插入到历史记录表中,以获取历史记录表的对应表中已更新的 任何 列。
编辑1 我已经指出 NOWHERE 在我的职位,我在寻找源代码,这样任何人耻辱,downvotes我,认为我在找那个。您可以查看我以前的问题/答案,以了解我不是在寻找“免费源代码”的人。
正如我在原始问题中所说的那样,我正在寻找 如何 编写此代码。我已经检查了http://plsql-tutorial.com/plsql- triggers.htm,有一个代码块显示了如何在ONE列更新时编写触发器。我认为也许有人会为我介绍的场景提供更通用的触发器的专业知识。
假设使用常规表而不是对象表,则没有很多选择。您的触发器必须是某种形式的
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…COLUMN<<n>>从数据字典字符串(USER_TAB_COLS),而不是硬编码他们,但你还是要硬编码在列引用:new伪记录。
COLUMN1
COLUMN2
COLUMN<<n>>
USER_TAB_COLS
:new
您可以通过查询数据字典(USER_TAB_COLS或ALL_TAB_COLS最有可能的代码),使用DDL语句构建一个字符串,然后执行EXECUTE IMMEDIATE来执行DDL语句,从而编写一段上面生成触发器的代码。然后,每当将新列添加到任何表中时,您都必须调用此脚本,以重新创建该列的触发器。编写和调试这种DDL生成代码很繁琐,但在技术上并不是特别困难。但这很少值得,因为有人会不可避免地添加新列而忘记重新运行脚本,或者有人需要修改触发器来做一些额外的工作,而仅手动更新触发器要比修改和测试生成的脚本更容易。触发器。
ALL_TAB_COLS
EXECUTE IMMEDIATE
不过,更笼统地说,我会质疑以这种方式存储数据的智慧。在历史记录表中为修改后的每一行的每一列存储一行,这使得使用历史记录数据非常具有挑战性。如果某人想知道特定行在特定时间点处的状态,则必须将历史记录表自身连接N次,其中N是该时间点表中的列数。这将是非常低效的,很快就会使人们避免尝试使用历史数据,因为他们无法在合理的时间内使用有用的东西而不会扯掉头发。它’ 通常,使用一个具有与活动表相同的列集的历史记录表(添加一些用于跟踪日期等)的历史记录表以及每次更新该行时,在历史记录表中插入一行更为有效。那会消耗更多的空间,但是通常更容易使用。
Oracle有多种审计数据更改的方法-AUDIT您可以使用DML,可以使用细粒度审计(FGA),可以使用Workspace Manager或可以使用Oracle Total Recall。如果您要寻找比编写自己的触发代码更多的灵活性,那么我强烈建议您研究这些本质上更自动化的其他技术,而不是尝试开发自己的架构。
AUDIT