小编典典

PL SQL触发器,用于在更新列时插入历史记录

sql

当表中的 任何 列更新时,我想在历史表中插入一行。

我只是想捕获列名,旧值和新值。

我希望此触发器尽可能重用,因为我将在其他表上使用相同的概念。

我熟悉触发器以及如何捕获某一列上的更新。我特别在寻找如何编写 一个 触发器,以将一条记录插入到历史记录表中,以获取历史记录表的对应表中已更新的
任何 列。

编辑1
我已经指出 NOWHERE
在我的职位,我在寻找源代码,这样任何人耻辱,downvotes我,认为我在找那个。您可以查看我以前的问题/答案,以了解我不是在寻找“免费源代码”的人。

正如我在原始问题中所说的那样,我正在寻找 如何 编写此代码。我已经检查了http://plsql-tutorial.com/plsql-
triggers.htm,有一个代码块显示了如何在ONE列更新时编写触发器。我认为也许有人会为我介绍的场景提供更通用的触发器的专业知识。


阅读 235

收藏
2021-04-28

共1个答案

小编典典

假设使用常规表而不是对象表,则没有很多选择。您的触发器必须是某种形式的

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;

你可以取COLUMN1COLUMN2COLUMN<<n>>从数据字典字符串(USER_TAB_COLS),而不是硬编码他们,但你还是要硬编码在列引用:new伪记录。

您可以通过查询数据字典(USER_TAB_COLSALL_TAB_COLS最有可能的代码),使用DDL语句构建一个字符串,然后执行EXECUTE IMMEDIATE来执行DDL语句,从而编写一段上面生成触发器的代码。然后,每当将新列添加到任何表中时,您都必须调用此脚本,以重新创建该列的触发器。编写和调试这种DDL生成代码很繁琐,但在技术上并不是特别困难。但这很少值得,因为有人会不可避免地添加新列而忘记重新运行脚本,或者有人需要修改触发器来做一些额外的工作,而仅手动更新触发器要比修改和测试生成的脚本更容易。触发器。

不过,更笼统地说,我会质疑以这种方式存储数据的智慧。在历史记录表中为修改后的每一行的每一列存储一行,这使得使用历史记录数据非常具有挑战性。如果某人想知道特定行在特定时间点处的状态,则必须将历史记录表自身连接N次,其中N是该时间点表中的列数。这将是非常低效的,很快就会使人们避免尝试使用历史数据,因为他们无法在合理的时间内使用有用的东西而不会扯掉头发。它’
通常,使用一个具有与活动表相同的列集的历史记录表(添加一些用于跟踪日期等)的历史记录表以及每次更新该行时,在历史记录表中插入一行更为有效。那会消耗更多的空间,但是通常更容易使用。

Oracle有多种审计数据更改的方法-AUDIT您可以使用DML,可以使用细粒度审计(FGA),可以使用Workspace
Manager或可以使用Oracle Total
Recall。如果您要寻找比编写自己的触发代码更多的灵活性,那么我强烈建议您研究这些本质上更自动化的其他技术,而不是尝试开发自己的架构。

2021-04-28