您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

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

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

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

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。如果您要寻找比编写自己的触发代码更多的灵活性,那么我强烈建议您研究这些本质上更自动化的其他技术,而不是尝试开发自己的架构。

SQLServer 2022/1/1 18:42:10 有559人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶