1

挿入トリガーを取得して、挿入されるレコードとは異なるレコードの同じテーブルの値を更新する方法はありますか? Informix では、トリガーがオンになっている同じテーブルの値を更新できないため、私が理解しているように、これを行うことはできないようです。ストア プロシージャから値を返し、トリガーで "into" ステートメントを使用する提案を見てきましたが、更新は別のレコードで行う必要があるため、この概念は私の場合には機能しないと思います。挿入中。

どんな提案でも大歓迎です。

4

2 に答える 2

2

実はこんな方法も…

トリガー元と同じテーブル/列を直接更新することはできませんが、ビューと「代わりに」トリガーを使用する簡単な回避策があり、常に機能しています。

  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;

ここで、ビューの基礎となる同じテーブルの他の行を更新する挿入トリガーを実行します (この例では、開始日/終了日の重複を避けるため)。ビューとテーブルの名前をうまく組み合わせることで、サブクエリで参照されるテーブルの更新に関するエラー (トリガーの 2 番目の更新) を回避することもできます。

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
    );
于 2016-12-09T14:32:59.533 に答える
0

この質問はids@iiug.orgメーリング リストで行われましたが、それを行う方法はないとの意見が一致しました — 私もその意見に同意します。

于 2013-04-01T17:41:05.300 に答える