【问题标题】:PL/SQL: Is it possible to access the :NEW / :OLD with a variable holding the column name?PL/SQL:是否可以使用包含列名的变量访问 :NEW / :OLD ?
【发布时间】:2014-05-28 04:33:19
【问题描述】:

首先感谢您调查我的问题。那么现在我的问题。我正在制作一个触发器,以监听 UPDATES 在日志文件中写入哪些列已更改并写入该列的新/旧值。

例如有一个包含这些列的表:

[ID]       [NAME]       [AGE]
1          Me           18

如果我现在打电话:

UPDATE TABLE VALUES(1, 'Not Me', 19);

它应该记录:

[NAME], Me, Not Me
[AGE], 18, 19

首先,我想动态获取列名,以便我的触发器可以动态工作。那行得通,我最终将列名放在了一个变量中,例如:

x.column_name

我知道如何使用 :OLD / :NEW 但是我想不出办法

e.g. :OLD.Id
:OLD => x.column_name                // where x.column_name would hold Id

我不太确定这是否根本不可能,或者我只是在 SQL 上遗漏了一些重要的东西。

提前感谢您的任何回答;)

【问题讨论】:

标签: sql oracle plsql


【解决方案1】:

您不能动态引用记录中的列(或像:new:old 这样的伪记录)。对列名的引用必须是静态的。

但是,您可以动态生成触发器(尽管这意味着您每次添加或删除列时都需要重新生成触发器)。对此有多种方法,这里是one AskTom example,它使用 SQL*Plus 脚本动态生成触发器。

不过,退一步说,我总是很怀疑以这种方式存储审计数据。当每个更改的列都作为单独的行存储在审计表中时,审计表会变得非常大,并且运行查询以查看行的先前状态需要为表中的每一列将表连接到自身一次。这通常会很快变得非常缓慢。

【讨论】:

  • 根据我的经验,“每个字段 1 行”审计很丑陋,浪费空间,而且难以解释。我发现更好的是让您的审计表记录“之后”值(例如所有 :NEW 值)以及更改的日期/时间(TIMESTAMP(9)),除了您记录的 DELETE :旧值。这样就可以查询审计表,按变更时间戳排序,版本变化一目了然。
  • 关于性能和丑陋我只是在学校练习中玩了一下。所以这两件事对我来说并不重要。
【解决方案2】:

我能够使用 OTN 论坛上提供的 the solution 将更改记录到日志表中。

为了让它工作,我创建了如下支持表:

CREATE TABLE T_HISTORIE (hi_betreffende_tabelle varchar2(100),hi_betreffendes_feld varchar2(100),hi_wert_alt varchar2(100),hi_wert_neu varchar2(100));
CREATE TABLE T_HISTORIENSTEUERUNG (HS_TABELLE VARCHAR2(100),HS_FELD VARCHAR2(100));

T_HISTORIENSTEUERUNG 是一个表格,您可以在其中输入要记录的表格和列。例如,如果您有兴趣仅将更改记录到 NAME 列,那么您可以进行如下输入:

INSERT INTO T_HISTORIENSTEUERUNG VALUES ('TABLE', 'NAME');

T_HISTORIE 是日志表。它包含表名、列名、旧值和更改列值的每次更新的新值,该列已配置为记录(使用 T_HISTORIENSTEUERUNG 表)。您也可以添加进行更新的时间。您还需要修改 PL/SQL 包。

将记录对 TABLE 的所有后续更新。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-15
    • 2021-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-24
    • 2021-10-29
    • 1970-01-01
    相关资源
    最近更新 更多