【问题标题】:Oracle PL/SQL: Loop Over Trigger Columns DynamicallyOracle PL/SQL:动态循环触发列
【发布时间】:2010-10-21 15:59:06
【问题描述】:

在触发器内部,我试图遍历表中的所有列,并将新值与旧值进行比较。这是我目前所拥有的:

CREATE OR REPLACE TRIGGER "JOSH".TEST#UPD BEFORE 
UPDATE ON "JOSH"."TEST_TRIGGER_TABLE" REFERENCING OLD AS OLD NEW AS NEW FOR EACH ROW
declare    
   oldval varchar(2000);   
   newval varchar(2000);   
begin    
   for row in (SELECT column_name from user_tab_columns where table_name='TEST_TRIGGER_TABLE') loop  
     execute immediate 'select :old.'||row.column_name||' from dual'   into oldval;  
     execute immediate 'select :new.'||row.column_name||' from dual'   into newval;  
     --Do something here with the old and new values
   end loop;  
end;

触发器编译,但是当触发器触发时,我得到:

ORA-01008:并非所有变量都绑定

在第一次执行时立即执行,因为它需要 :old 的值。 :old:new 已经定义为触发器的一部分,但执行立即似乎看不到这些变量。

有没有办法动态迭代触发器中的列值?

【问题讨论】:

  • 只有当您指定触发器为 FOR EACH ROW 时,:old 和 :new 关键字才可用。
  • 对,指定了“FOR EACH ROW”。问题是我试图在动态 sql 语句中引用它们。
  • 刚刚添加了我用来创建触发器以避免混淆的完整 DDL。

标签: oracle dynamic plsql database-trigger


【解决方案1】:

您实际上是在尝试构建自己的系统来审核对表的所有更改吗? (我的最佳猜测是您可能会对任意列的旧值和新值执行什么操作。)如果是这样,您可能需要研究 Oracle 自己的审计功能。

【讨论】:

    【解决方案2】:

    不,您不能动态引用 :old 和 :new 值。正如 Shane 建议的那样,您可以编写代码来生成静态触发代码,如果这样可以让生活更轻松。此外,您可以将“在这里做某事”放入一个包过程中,以便您的触发器变为:

    CREATE OR REPLACE TRIGGER JOSH.TEST#UPD BEFORE 
    UPDATE ON JOSH.TEST_TRIGGER_TABLE
    begin    
       my_package.do_something_with (:old.col1, :new.col1);
       my_package.do_something_with (:old.col2, :new.col2);
       my_package.do_something_with (:old.col3, :new.col3);
       -- etc.
    end;
    

    (顺便说一句,你可以放弃毫无意义的 REFERENCING 子句)。

    【讨论】:

      【解决方案3】:

      我也遇到过类似的问题,虽然是在 MSSQL 中。

      我的解决方案是编写一个存储过程,它遍历表和列信息(通过字典视图或自定义存储库)并生成所需的触发器。仅当数据模型发生更改时才需要运行该过程。

      优点是您不必在每次更新时都在元模型中游弋,而是提前生成触发器。

      【讨论】:

        【解决方案4】:

        我不确定你是否能做你想做的事。您不想在 PL/SQL 代码中显式命名表列的原因是什么?如果表字段经常更改,您可以构建 PL/SQL,为每个表动态构建 PL/SQL 触发器(每个表中都有明确的字段名称)。每次表更改时,您都可以运行该 PL/SQL 来生成新触发器。

        【讨论】:

        • 我有点担心可能是这种情况。我只是试图让代码尽可能简单,避免一遍又一遍地把相同的代码弄得一团糟。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-04-07
        • 1970-01-01
        • 2012-04-20
        • 1970-01-01
        • 2020-12-04
        • 2016-08-03
        相关资源
        最近更新 更多