当前位置: 首页 > 面试题库 >

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

吕自怡
2023-03-14
问题内容

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

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

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

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

编辑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;

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



 类似资料:
  • 问题内容: 是否可以为表的插入和更新事件触发mysql触发器? 我知道我可以做到以下几点 但是我该怎么办 是否可以,或者我必须使用2个触发器?两者的代码都相同,我不想重复。 问题答案: 您必须创建两个触发器,但是您可以将通用代码移动到过程中并使它们都调用过程。

  • 问题内容: 所以我有两个这样的桌子… 我正在尝试创建一个触发器,该触发器将: 更新时被更新。 为了进一步使事情复杂化, 如果在when 更新中不存在,我想将其插入并设置为1。 我一直在寻找类似的问题: 1. 在使用自动增量字段插入触发器之前/之后,以及 2. 使用触发器来更新另一个数据库中的表以 尝试将2.合并在一起。这是我到目前为止的内容: 任何建议和指示,我们将不胜感激。或者可能是我忽略的另一

  • 我的Mysql数据库中有一些历史数据表。 我想在同一张表中为另一天重复一天的历史数据。 表结构,带有一些示例数据: 我想重复这些ID和值,但需要一个新的日期-例如2012-05-01。即增加: 我觉得应该有一个直截了当的方法来做这件事...我试过使用UPDATE语句和子查询,并使用多个左联接,但还没有达到目的。 我能怎么做吗? 编辑:以澄清...-我不想将这些添加到新表中-我也不想更改表中的现有记

  • 问题内容: 由于MySQL忽略了检查约束,如何使用触发器来阻止插入或更新的发生? 例如: 表foo有一个称为agency的属性,并且agency属性只能是1、2、3、4或5。 还是有更好的方法来进行MySQL中的检查约束? 问题答案: 尝试SIGNAL语法-https: //dev.mysql.com/doc/refman/5.5/en/signal.html 编辑 根据Bill Karwin下面

  • 我试图创建一个触发器,将新插入和/或更新的记录从一个表复制到该表的历史版本。其目的是在每次插入和/或更新表中的记录时保留一条记录。 这是我拥有的创建触发器语句语法,遵循IBMDb2触发器站点。 我收到的错误是: [代码:-104,SQL状态: 42601]在N.LIFECYCLE_STATUS)之后发现了一个意外的令牌END-OF-STATEMENT。预期的令牌可能包括:""... SQLCODE

  • 我创建了一个用于插入和更新的SQL触发器,它基本上执行以下操作: 从插入的表中获取LineID(表的PrimaryID)和RegionID,并将其存储在INT变量中。然后,它对连接表进行检查,以找到RegionID应该是什么,如果RegionID不等于插入表中应该是什么,那么它应该更新该记录。 我的问题是,它没有更新记录,我猜,这是因为记录还没有插入到PurchaseOrderLine表中,我正在