2017-08-09 9 views
1

Iは、他の列の間で、格納するために使用される4つの列を持つテーブルを持っている:Informixでエラーコード-747を解決するには?

行が挿入された
  • created_tm)行があった場合、行(created_by
  • を挿入した
  • 更新(last_updated
  • 行を更新した
  • updated_by

私はPOPUにトリガーを作成しましたlast_updated後半とupdated_by更新ステートメントが発生するたびにこの問題を回避する方法はあり

[Code: -747, SQL State: IX000] Table or column matches object 
referenced in triggering statement. 

create trigger my_table_audit update on my_table referencing old as pre new as post  
for each row 
(
    update my_table set last_updated = CURRENT year to second, 
    updated_by = USER where (id = pre.id) 
); 

をしかし、私は特定の行の通常の列を更新する場合、更新がで失敗しますトリガーを実行するテーブルの個々の列をすべて明示的に指定する必要はありませんか?

答えて

2

Informixでは、定義されている表を操作するトリガーにはいくつかの制約があります。リストは広範囲であるので、私は唯一のオンラインドキュメント(バージョン12.10)リンク:あなたのケースで

を、可能な解決策は、にトリガプロシージャを利用することですInformix trigger to change inserted valuesへの回答でceinmartで説明されているように、挿入/更新の値を操作します。

だから、トリガプロシージャを使用して、それがこのようなものになるだろう:

CREATE TABLE self_audit 
(
    id    SERIAL PRIMARY KEY CONSTRAINT pk_self_audit 
    , col1   CHAR(3) 
    , created_tm  DATETIME YEAR TO FRACTION 
    , created_by  CHAR(10) 
    , last_updated DATETIME YEAR TO FRACTION 
    , updated_by  CHAR(10) 
); 

CREATE PROCEDURE spti_self_audit() 
REFERENCING NEW AS new_insert FOR self_audit; 

    LET new_insert.created_tm = CURRENT; 
    LET new_insert.created_by = USER; 
    LET new_insert.last_updated = CURRENT; 
    LET new_insert.updated_by = USER; 

END PROCEDURE; 

CREATE TRIGGER ti_self_audit INSERT ON self_audit 
REFERENCING NEW AS new_insert 
FOR EACH ROW 
(
    EXECUTE PROCEDURE spti_self_audit() WITH TRIGGER REFERENCES 
); 

CREATE PROCEDURE sptu_self_audit() 
REFERENCING NEW AS post OLD AS pre FOR self_audit; 

    LET post.last_updated = CURRENT; 
    LET post.updated_by = USER; 

END PROCEDURE; 

CREATE TRIGGER tu_self_audit UPDATE ON self_audit 
REFERENCING NEW AS post OLD AS pre 
FOR EACH ROW 
(
    EXECUTE PROCEDURE sptu_self_audit() WITH TRIGGER REFERENCES 
); 

トリガ・ルーチンのこのタイプの私の理解では、私たちが直接複数の更新プログラムを更新/挿入される値を操作する代わりにやっているということです/トリガーアクションを介して挿入します。この場合

、私の更新トリガーは、列last_updatedupdated_byの値を操作するので、ユーザは、列created_tmcreated_byの値を変更することができます。

+0

説明とソリューションLuisに感謝します。私は、 'CURRENT、USER'を返す関数を定義し、' function function populate_audit_fields()をmy_table_audit'のように実行する、少し異なるソリューション(DBAが提案)を使用しました。あなたが考えることができるストアドプロシージャと比較して、賛否両論はありますか? – Behrang

+0

@ Behrang Informixでは内部的に扱われるかどうかはわかりませんが、結果は同じようです。ベンチマークをしたいのでなければ、あなたのために働くものを使用してください。 –

関連する問題