Informix插入触发器:更新同一个表但不同记录的值

时间:2013-03-18 01:19:24

标签: triggers informix

有没有什么方法可以获得一个插入触发器来更新不同记录中同一个表上的值到正在插入的值?根据我的理解,Informix似乎不允许我这样做,因为它不允许您更新触发器所在的同一个表中的值。我已经看到了一些建议,你从商店程序返回值并在触发器中使用“into”语句,但我不认为这个概念在我的情况下有效,因为更新需要在一个不同的记录上完成插入。

任何建议都将不胜感激。

2 个答案:

答案 0 :(得分:2)

实际上有办法做到这一点......

确实,您无法直接更新同一个表/列 触发,但有一个简单的解决方法使用 视图和“而不是”触发器总是对我有效。

  1. 重命名表格
  2. 使用原始名称
  3. 在该表上创建一个视图
  4. 在视图上创建一个“而不是”触发器,然后写入原始表
  5. 通过撤销原始表格上的所有权利来强制使用视图
  6. 以下是问题的现实生活示例 -​​ 具有日期范围的价格表, 每当需要更新同一项目的其他行时 插入,更新,删除已完成,以避免具有日期范围 重叠(同一日期的价格超过一个)。

    价目表:

    item    valid_from   valid_to       price
     01     2010-01-01   2013-03-15    120.00
     01     2013-04-16   2015-12-31    125.00
     01     2016-01-01   2016-05-05    130.00
     01     2016-05-06                 140.00
    

    首先,使用相同名称的视图替换表:

    RENAME TABLE pricelist TO pricelist_table;
    CREATE VIEW pricelist AS SELECT * FROM pricelist_table;
    REVOKE ALL ON pricelist_table FROM public;
    GRANT ALL ON pricelist TO public;
    

    现在执行一个插入触发器来更新同一个表的其他行 视图的基础(在此示例中为了避免与日期重叠)。 通过处理视图和表名称,您还可以避免错误 更新子查询中引用的表(触发器中的第二个更新)。

    CREATE TRIGGER ins_pricelist INSTEAD OF INSERT ON pricelist
           REFERENCING new AS new
       FOR EACH ROW (
    
         -- write the data to the real table
         insert into pricelist_table
         values(new.item,new.valid_from,new.valid_to,new.price),
    
         -- close off the previous price row by setting its "valid_to" date
         update pricelist_table set valid_to = new.valid_from - 1
          where item = new.item and valid_from < new.valid_from
            and ( valid_to >= new.valid_from or valid_to is null ),
    
         -- if the row we're inserting has a null "valid_to" date,
         -- set it to the day before the next "valid_from" date
         update pricelist set valid_to =
              (select min(valid_from)-1 from pricelist_table
                where item = new.item and valid_from > new.valid_from)
          where item = new.item and valid_from = new.valid_from
            and valid_to is null
       );
    

    在支持带触发器引用的过程的更高版本(11+)上, 更好,更可维护的方法是调用单独的存储过程 来自触发器:

    CREATE PROCEDURE write_pricelist()
           REFERENCING old AS old  new AS new  FOR pricelist;
    
      -- do all your inserts, updates, etc to pricelist_table here ...
    
    END PROCEDURE;
    
    -- These triggers all call the same stored procedure (above).
    CREATE TRIGGER ins_pricelist INSTEAD OF INSERT ON pricelist
        REFERENCING new AS new
        FOR EACH ROW (
          EXECUTE PROCEDURE write_pricelist() WITH TRIGGER REFERENCES
        );
    CREATE TRIGGER upd_pricelist INSTEAD OF UPDATE ON pricelist
        REFERENCING new AS new old AS old
        FOR EACH ROW (
          EXECUTE PROCEDURE write_pricelist() WITH TRIGGER REFERENCES
        );
    CREATE TRIGGER del_pricelist INSTEAD OF DELETE ON pricelist
        REFERENCING old AS old
        FOR EACH ROW (
          EXECUTE PROCEDURE write_pricelist() WITH TRIGGER REFERENCES
        );
    

答案 1 :(得分:0)

ids@iiug.org邮件列表中询问了这个问题,并且认为没有办法实现这一点 - 并且我同意共识。