是否可以(我假设:是)从触发器(Firebird 2.5)更新其他表。 例如,我有一个表X ,更新后触发器如下:
begin
if (new.CODE<>old.CODE) then
BEGIN
post_event 'CODE_CHANGE';
UPDATE Y SET CODE=10 WHERE ID=1;
END
end
或
begin
if (new.CODE<>old.CODE) then
BEGIN
post_event 'CODE_CHANGE';
EXECUTE STATEMENT ('UPDATE Y SET CODE=10 WHERE ID=1');
END
end
但它不起作用(表格Y 不会改变)。
触发器的完整定义(为了更好地理解)
SET TERM ^^ ;
CREATE TRIGGER ABC FOR X ACTIVE AFTER INSERT OR UPDATE OR DELETE POSITION 0 AS
begin
if (new.CODE<>old.CODE) then
BEGIN
post_event 'CODE_CHANGE';
EXECUTE STATEMENT ('UPDATE Y SET CODE=10 WHERE ID=1');
END
post_event 'CHANGE';
end ^^
第二个问题:如何为UPDATE命令提供参数(对于表Y ) - 我的意思是我想在上面的代码中放置 10 “ > new.CODE (来自表格X 的新值)类似这样的内容:
UPDATE Y SET CODE=new.CODE WHERE ID=1
感谢您的建议。
ARTIK
答案 0 :(得分:2)
是的,您可以操纵触发器中的任何表,但不限于与触发器关联的表。所以问题是为什么触发器中的UPDATE
语句不起作用?我看到三种可能性:
if (new.CODE<>old.CODE) then
声明。如果new
的{{1}}或old
值为code
,NULL
部分将无法运行。有关完整说明,请参阅Firebird Null Guide。这里的解决方案是使用DISTINCT
operator。当然,如果then
值没有改变,那么if语句也“失败”,但这应该是显而易见的:)另外,如果你收到code
事件,你可以确定if staement运行。
另请注意,在多操作触发器中,如果触发器由CODE_CHANGE
触发,则NEW将为NULL
,如果触发器为DELETE
,则OLD为NULL
由INSERT
解雇。所以你的触发器只能在UPDATE语句的情况下按预期工作。您可能希望将其拆分为三个不同的触发器。where
部分失败,即表格Y中没有ID = 1的记录。可能的解决方案是使用UPDATE OR INSERT
statement。commit
这笔交易吗?如果您将其回滚,则不仅会在“主表”中回滚所有表中的更改。从第二个问题开始 - 是的UPDATE语句看起来没问题,在任何语句中使用触发器上下文变量都是有效的。您可以在语句中使用其前缀为冒号,即
来使用其他变量UPDATE Y SET CODE = :SomeVariable WHERE ID=1