冲突触发器 - 变异表
我在 Oracle 中的变异表上遇到问题。我有两个表:Customer
和 Person
。在修改 Person
行期间,我必须更新 Customer
中的 ChangeDate
,因此我创建了一个触发器。不幸的是,Customer
上有一个触发器,在某些情况下会更新 Person
,从而导致变异表问题。幸运的是,如果此更改是由 Customer
更改引起的,则在更新 Person
时我不必更新 Customer.ChangeDate
。
所以这是我的问题:如何识别 Person
触发器是由 Customer
触发器触发的?
I have a problem with a mutating table in Oracle. I have two tables, Customer
and Person
. I must update ChangeDate
in Customer
during modification of a Person
row, so I created a trigger. Unfortunately there is a trigger on Customer
which updates Person
in some cases and that is causing a mutating table problem. Fortunately I don't have to update Customer.ChangeDate
when updating Person
if this change was caused by a Customer
change.
So here is my question: how can I recognize that the Person
trigger was fired by the Customer
trigger?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
变异表错误几乎总是表明数据模型或相关业务流程存在问题。最常见的原因是非规范化,即一个表中的数据以某种方式复制到另一个表中。这里的情况似乎就是这样 - 您的 CUSTOMER 表保存着有关另一个表 PERSON 的元数据。只是它是由另一个方向的级联信息复合而成的。
解决这种情况的正确方法是对数据模型进行梳理。 CUSTOMER 是 PERSON 的子类型还是反之亦然?确定哪个是父级,哪个是子级,并确保信息仅朝一个方向流动:可能从超类型到子类型。尽管更好的解决方案是完全消除数据传播。
有一些解决方法,但它们涉及包和其他应用更改的设计。
Mutating table errors almost always indicate a problem with the data model or related business processes. The most common cause is denormalisation, that is where data in one table is duplicated in some fashion in another table. That seems to be the case here - your CUSTOMER table is holding metadata about another table, PERSON. Only it's compounded by the cascade of information in the other direction.
The proper way to resolve this situation is to sort out the data model. Is CUSTOMER a sub-type of PERSON or is it the other way round? Determine which is the parent and which is the child, and make sure that information only flows in one direction: probably from super-type to sub-type. Although a better solution would be to remove the data propagation altogether.
There are workarounds but they involve packages and other contrivances to apply changes.
@APC 是完全正确的。
我会通过记住我无法协商对数据模型进行更正的时间来做出一些妥协。在这种情况下,您可能需要使用包内的变量作为一个触发器来向另一个触发器发出信号。
您还可以将 WHEN 条件放入触发器执行子句中。
最后,如果您感觉像一个真正的黑客,您可以询问 PL/SQL 调用堆栈并在那里查找其他触发器。
@APC is completely correct.
I'll compromise a bit by remembering the times that I was not able to negotiate a correction to the data model. In such a case, you may want to use a variable inside a package for one trigger to signal the other.
You can also put WHEN conditions in the trigger execution clause.
Finally if you're feeling like a real hacker, you can interrogate the PL/SQL call stack and look for other triggers there.
最后,我使用
全局临时表
并在提交后进行清除:Finally I'm used
global temporary table
with clearing after commit: