如何解决 Informix 中的错误代码 -747?
How to resolve error code -747 in Informix?
我有一个 table,除其他列外,还有 4 列用于存储:
- 插入一行时 (
created_tm
)
- 谁插入了行 (
created_by
)
- 更新行时 (
last_updated
)
- 谁更新了行(
updated_by
)
我创建了一个触发器来填充 last_updated
和 updated_by
每当发生更新语句时:
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)
);
然而,当我更新特定行的普通列时,更新失败并显示:
[Code: -747, SQL State: IX000] Table or column matches object
referenced in triggering statement.
有没有一种方法可以解决这个问题,而不必显式命名 table 中触发的所有单独列?
在 Informix 中,操作 table 定义它们的触发器受到一些限制。该列表很广泛,所以我只 link 在线文档(版本 12.10):
在您的情况下,一个可能的解决方案是使用触发器程序来操纵 inserts/updates 的值,如 ceinmart in his answer to Informix trigger to change inserted values 所述。
所以使用触发程序,它会是这样的:
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
);
我对这种类型的触发器例程的理解是,我们直接操纵将成为 inserted/updated 的值,而不是通过触发器操作做更多 updates/inserts。
在这种情况下,我的更新触发器仅操作列 last_updated
和 updated_by
的值,因此用户可以更改列 created_tm
和 [=14] 的值=].
我有一个 table,除其他列外,还有 4 列用于存储:
- 插入一行时 (
created_tm
) - 谁插入了行 (
created_by
) - 更新行时 (
last_updated
) - 谁更新了行(
updated_by
)
我创建了一个触发器来填充 last_updated
和 updated_by
每当发生更新语句时:
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)
);
然而,当我更新特定行的普通列时,更新失败并显示:
[Code: -747, SQL State: IX000] Table or column matches object
referenced in triggering statement.
有没有一种方法可以解决这个问题,而不必显式命名 table 中触发的所有单独列?
在 Informix 中,操作 table 定义它们的触发器受到一些限制。该列表很广泛,所以我只 link 在线文档(版本 12.10):
在您的情况下,一个可能的解决方案是使用触发器程序来操纵 inserts/updates 的值,如 ceinmart in his answer to Informix trigger to change inserted values 所述。
所以使用触发程序,它会是这样的:
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
);
我对这种类型的触发器例程的理解是,我们直接操纵将成为 inserted/updated 的值,而不是通过触发器操作做更多 updates/inserts。
在这种情况下,我的更新触发器仅操作列 last_updated
和 updated_by
的值,因此用户可以更改列 created_tm
和 [=14] 的值=].