【问题标题】:Oracle: excluding updates of one column for firing a triggerOracle:排除一列的更新以触发触发器
【发布时间】:2010-11-28 03:26:37
【问题描述】:

在 oracle 中,我可以指定应该触发触发器的列:

create or replace trigger my_trigger
before update of col1, col2, col3 on my_table for each row
begin
  // the trigger code will be executed only if col1 or col2 or col3 was updated
end;

现在我想做以下事情:我不希望触发器在只有一个列被更新时触发。这怎么可能?

我可以列出除一个之外的所有列,这不应该引发触发器的触发。这对于有很多列的表来说是相当麻烦的。

另一种方法是像这样使用 UPDATING 函数:

if not updating('COL3') then ...

但如果我同时更改 COL1 COL3,则该语句的计算结果为 false。这不是我想要的,因为我想在 只有一个 列 (COL3) 被更新时限制执行。

【问题讨论】:

  • 使用数据字典列出所有列不那么麻烦。 SELECT column_name FROM user_tab_columns WHERE table_name = 'MY_TABLE' AND column_name != 'COL3';
  • 确实如此,但需要其他人来维护触发器。如果我们要添加一个新列或重命名它……我已经能听到他大声喊叫了。我想找到一个可靠的方法,对他,尤其是对我来说,痛苦更少。 ;-)

标签: sql oracle plsql triggers


【解决方案1】:

你可以这样做:

create or replace trigger my_trigger
before update on my_table
for each row
declare
   n_cols integer := 0;
begin
   for r in (select column_name from all_tab_columns
             where table_name = 'MY_TABLE'
             and owner = 'MY_SCHEMA')
   loop
      if updating(r.column_name) then
         n_cols := n_cols + 1;
         exit when n_cols > 1;
      end if;
   end loop;
   if n_cols > 1 then
      do_something;
   end if;
end;

虽然可能效率不高!

【讨论】:

    【解决方案2】:

    我昨天也遇到了同样的问题。 我想编写一个触发器,该触发器在除一个之外的每个字段上触发,该表有 103 列。

    首先我编码:

    if (:OLD.col1<>:NEW.col1 or :OLD.col2<>:NEW.col2 or :OLD.col3<>:NEW.col3 ....)
    

    但我对空值有一些问题,所以我补充说:

    if (NVL(:OLD.col1,0)<>NVL(:NEW.col1,0) or NVL(:OLD.col2,0)<>NVL(:NEW.col2,0)  ....)
    

    但后来我在使用 DATE 列时遇到了一些问题,变得一团糟..

    我认为最好的解决方案是在“OF”中列出您要验证的所有列:

    AFTER INSERT OR UPDATE of cOL1, col2, col3 ... colN ON table1
    

    它并不“优雅”,但……它工作得很好。

    【讨论】:

      【解决方案3】:

      这可能不是您想听到的答案,但我认为您过于夸大了维护负担。表的结构在投入生产后经常更改是不正常的。如果您确实有一个经常更改列号或名称的表,那么我建议您遇到更大的架构问题。

      所以,现在只需输入所有列名,然后等待维护是否成为问题。为了避免偶尔更改 DDL 脚本,在触发器中编写复杂的实现当然是不值得的 - 您将为每次更新支付税款。

      【讨论】:

        【解决方案4】:

        我认为没有办法可以避免列出表中的所有其他列,无论是在触发器正文中还是在 before update of ... 子句中。

        但是,如果添加或删除了任何列,您也许可以在表上编写更改触发器以自动重新生成更新触发器。工作量有点大,但维护应该是自动的。

        【讨论】:

          猜你喜欢
          • 2017-11-08
          • 1970-01-01
          • 2012-04-20
          • 1970-01-01
          • 2016-12-03
          • 2011-10-25
          • 1970-01-01
          • 1970-01-01
          • 2016-06-24
          相关资源
          最近更新 更多