Triggers 递归触发器-一个触发器释放另一个触发器(update语句)

Triggers 递归触发器-一个触发器释放另一个触发器(update语句),triggers,sql-update,firebird,Triggers,Sql Update,Firebird,我在我的小数据库(2个表数据库)中创建了5个触发器 在我添加最后一个后(在更新INVOICE.SYMBOL后更改INVPOS.INVSYMBOL),这些触发器相互激活,我得到一个 Too many concurrent executions of the same request. 错误 你能看看我创建的触发器并帮我解决吗 我能做些什么来避免将来出现这些问题?我应该将几个触发器合并为一个吗?您应该避免触发器之间的循环引用 通常,触发器不适用于复杂的业务逻辑,它们适用于简单的“if-then”

我在我的小数据库(2个表数据库)中创建了5个触发器

在我添加最后一个后(在更新INVOICE.SYMBOL后更改INVPOS.INVSYMBOL),这些触发器相互激活,我得到一个

 Too many concurrent executions of the same request.
错误

你能看看我创建的触发器并帮我解决吗


我能做些什么来避免将来出现这些问题?我应该将几个触发器合并为一个吗?

您应该避免触发器之间的循环引用

通常,触发器不适用于复杂的业务逻辑,它们适用于简单的“if-then”业务规则

对于您描述的情况,最好实现一个存储过程,在该过程中可以为所有表准备数据(执行数据检查、计算必要的值等),然后插入它们。它将导致直接、快速和易于维护的代码


另外,使用
CHECK
“防止将0插入
AMOUNT
PRICENET
”,以及“计算
NETVAL
”等任务的计算字段。您应该避免触发器之间的循环引用

通常,触发器不适用于复杂的业务逻辑,它们适用于简单的“if-then”业务规则

对于您描述的情况,最好实现一个存储过程,在该过程中可以为所有表准备数据(执行数据检查、计算必要的值等),然后插入它们。它将导致直接、快速和易于维护的代码


另外,使用
CHECK
来“防止将0插入
AMOUNT
PRICENET
”,以及“计算
NETVAL
”等任务的计算字段。一种解决方案是检查输入字段是否已更改,并且仅在确实需要(数据已更改)时运行触发器的操作,即

为T创建触发器Foo
作为
开始
--仅在Fld更改时执行update语句
如果(new.Fld与old.Fld不同),则开始
更新。。。
结束
结束
另一种选择是检查触发器是否已经完成了它在该事务中的工作,即

为T创建触发器Foo
作为
声明trgrDone VARCHAR(255);
开始
trgrDone=RDB$GET_CONTEXT('USER_TRANSACTION','Foo');
如果(trgrDone为空),则开始
--触发器尚未执行
--登记执行
rdb$set_上下文('USER_TRANSACTION','Foo',1);
--进行可能导致再入的工作
更新。。。
结束
结束

一种解决方案是检查Intrest字段是否已更改,并且只有在确实需要(数据已更改)时才运行触发器的操作,即

为T创建触发器Foo
作为
开始
--仅在Fld更改时执行update语句
如果(new.Fld与old.Fld不同),则开始
更新。。。
结束
结束
另一种选择是检查触发器是否已经完成了它在该事务中的工作,即

为T创建触发器Foo
作为
声明trgrDone VARCHAR(255);
开始
trgrDone=RDB$GET_CONTEXT('USER_TRANSACTION','Foo');
如果(trgrDone为空),则开始
--触发器尚未执行
--登记执行
rdb$set_上下文('USER_TRANSACTION','Foo',1);
--进行可能导致再入的工作
更新。。。
结束
结束

如果您在问题中包含相关细节,您可能会得到更好的回答。我使用触发器来实现一些所需的功能:防止将0插入金额和价格网、计算净值、从INVOICE.SYMBOL复制INVPOS.INVSYMBOL、计算SUMNETVAL、,更新INVOICE.SYMBOL时自动更改INVPOS.INVSYMBOL。我使用了几个触发器(更新前/更新后,有时插入时)。某些触发器执行更新查询以复制数据或计算某些值,从而激活其他触发器,而这些触发器则激活第一个触发器。我不知道如何修理它。我曾考虑将几个触发器合并成一个更大的触发器,但我认为这不会解决问题。回答这个问题需要哪些额外的信息?我的意思是在问题中包括相关细节(如DDL),而不是链接到数据库文件。如果DDL很大,那么您也可以链接到DDL脚本,这样人们就不必费力地下载和打开数据库。例如,从声音上看,
INVSYMBOL
要么是外键(在这种情况下可以自动更新),要么是非规范化数据(在这种情况下,您应该能够将其删除)。如果您在问题中包含相关详细信息,您可能会得到更好的回答。我使用触发器来实现一些所需的功能:防止将0插入金额和PRICENET、计算净值、从INVOICE.SYMBOL复制INVPOS.INVSYMBOL、计算SUMNETVAL、在更新INVOICE.SYMBOL时自动更改INVPOS.INVSYMBOL。I us编辑了一些触发器(更新前/更新后,有时插入时)。一些触发器执行更新查询以复制数据或计算某些值,因此它们会激活其他触发器,而这些触发器会激活第一个触发器。我不知道如何修复它。我曾考虑将几个触发器合并为一个更大的触发器,但我认为这不会解决问题。回答此问题需要哪些额外信息?什么我的意思是在你的问题中包括相关的细节(如DDL),而不是链接到数据库文件。如果DDL很大,那么你也可以链接到DDL脚本,这样人们就不必费力地下载和打开数据库。例如,从声音上看,
INVSYMBOL
是外键(在这种情况下,它可以自动更新)或它是非规范化数据(在这种情况下,您应该能够删除它)。我需要向我的数据库中再添加一项功能。如果INVOICE.STATUS更改为正数,则表示发票已被接受。一旦接受,链接列表的某些列将无法更改