2013-03-18 56 views
1

有沒有什麼辦法可以獲得插入觸發器來更新不同記錄中的同一張表上的值到正在插入的值?據我所知,Informix似乎不允許我這樣做,因爲它不允許您在觸發器所在的同一個表中更新值。我已經看到了從商店過程返回值並在觸發器中使用「into」語句的建議,但我不認爲這個概念適用於我的情況,因爲更新需要在不同的記錄上完成被插入。Informix插入觸發器:更新同一表但不同記錄的值

任何建議將不勝感激。

+0

這在[email protected]郵件列表上也詢問了問題,並且有人認爲沒有辦法做到這一點。我同意共識。 – 2013-03-19 06:30:21

+0

謝謝 - 這是一個非常煩人的'功能'。 – user2147475 2013-03-21 11:10:11

回答

0

[email protected]郵件列表上詢問此問題,並且有人認爲沒有辦法做到這一點 - 我同意共識。

1

其實是有辦法做到這一點...

這是事實,你不能直接更新同一表/列你 從觸發,但使用 觀點直截了當的解決方法和「而不是」觸發器,這對我來說總是有效。

  1. 重命名錶
  2. 創建該表的視圖,使用原始姓名
  3. 創建「而不是」的上視圖,其然後寫入到原來的表
  4. 強制使用的觸發通過撤銷原始表

這裏的一切權利的觀點是對提出的問題一個活生生的例子 - 價目表表日期範圍, 而其他行同樣項目需更新,只要 插入,更新,刪除完成,以避免日期範圍 重疊(同一日期多個價格)。

價格表:

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觸發器,更新同桌 的其他行的觀點基本(在這個例子中,爲了避免從/到日期重疊)。 通過處理視圖和表名,您還可以避免有關 更新子查詢中引用的表(觸發器中的第二個更新)的錯誤。

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+)與觸發引用的支持程序, 一個更好,更易於維護的方法是從觸發(S)調用一個單獨的存儲過程 :

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 
    ); 
相關問題