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

Triggers Informix插入触发器:更新同一个表上的值,但不同的记录,triggers,informix,Triggers,Informix,有没有办法让insert触发器将同一表中不同记录中的值更新为插入的记录?据我所知,Informix似乎不允许我这样做,因为它不允许您更新触发器所在表中的值。我看到过这样的建议,即从存储过程返回值,并在触发器中使用“into”语句,但我认为这个概念在我的情况下不起作用,因为更新需要在与插入的记录不同的记录上进行 如有任何建议,我们将不胜感激。此问题是在ids@iiug.org邮件列表,大家一致认为没有办法做到这一点,我同意大家的一致意见。实际上有办法做到这一点 确实,您不能直接更新正在更新的同一个

有没有办法让insert触发器将同一表中不同记录中的值更新为插入的记录?据我所知,Informix似乎不允许我这样做,因为它不允许您更新触发器所在表中的值。我看到过这样的建议,即从存储过程返回值,并在触发器中使用“into”语句,但我认为这个概念在我的情况下不起作用,因为更新需要在与插入的记录不同的记录上进行


如有任何建议,我们将不胜感激。

此问题是在
ids@iiug.org
邮件列表,大家一致认为没有办法做到这一点,我同意大家的一致意见。

实际上有办法做到这一点

确实,您不能直接更新正在更新的同一个表/列 从触发,但使用 视图和“代替”触发器一直对我有效

  • 重命名该表
  • 使用原始名称在该表上创建视图
  • 在视图上创建一个“代替”触发器,然后将其写入原始表
  • 通过撤消对原始表的所有权限来强制使用视图
  • 下面是一个实际问题的例子-一个包含日期范围的价格表, 其中,需要随时更新同一项目的其他行 完成插入、更新和删除,以避免日期范围 重叠(同一日期的多个价格)

    价格表:

    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;
    
    现在执行一个insert触发器来更新同一表的其他行 在视图的基础上(在本例中是为了避免从日期到日期的重叠)。 通过改变视图和表名称,还可以避免有关的错误 更新子查询中引用的表(触发器中的第二次更新)


    这个问题也在会议上提出ids@iiug.org邮件列表,人们一致认为没有办法做到这一点。我同意大家的共识。谢谢-这是一个非常烦人的“功能”。
    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
       );
    
    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
        );