Oracle 使用相同的表进行验证
我的桌子:Oracle 使用相同的表进行验证,oracle,validation,triggers,mutating-table,Oracle,Validation,Triggers,Mutating Table,我的桌子: parent (id number) child (id number, parent_id number, allocation number) 所以,对于每个父表,子表中都有三条固定记录。而且,我需要设置一个验证块,以限制用户更新子表中大于100%的三个子表中的任何一个子表的分配(对于任何给定的父表id) 我添加了一个触发器来检查给定父id的分配和,如果它大于100%,则引发异常。然而,这导致了一个突变问题。为克服此问题而提出的任何设计改进/建议或实现此目的的任何替代方案
parent (id number)
child (id number, parent_id number, allocation number)
所以,对于每个父表,子表中都有三条固定记录。而且,我需要设置一个验证块,以限制用户更新子表中大于100%的三个子表中的任何一个子表的分配(对于任何给定的父表id)
我添加了一个触发器来检查给定父id的分配和,如果它大于100%,则引发异常。然而,这导致了一个突变问题。为克服此问题而提出的任何设计改进/建议或实现此目的的任何替代方案
PS:应用程序截取oracle异常,并将其转换为
应用程序中的红色条错误消息;因此
显示错误消息时必须出现RAISE_应用程序_错误
编辑1:这里的问题是应用层,它允许在列表屏幕上进行编辑。多条记录可以一次更新,因此子表上的触发器将被多次触发。在每个触发器实例中,我们还需要检查其他子项的分配,这会导致突变问题。您不能在定义触发器的表上执行DML In触发器,您可以将结果视为突变触发器错误
一种替代方法是引入另一个表,比如sum_parent,在该表中可以维护每个父id的分配号之和,在子表的触发器中,可以从该表(sum_parent)中获取数据,执行检查,然后更新该表(sum_parent)在触发器本身内部使用新的和。仅使用DDL的解决方案。无触发器:
CREATE TABLE child
( id number NOT NULL,
parent_id number NOT NULL,
allocation number NOT NULL,
我们将添加一些需要的列:
child_no number NOT NULL, -- a number from 1 to 3
prev_child_no number NOT NULL, -- previous child number
running_total number NOT NULL, -- running total of allocations
prev_running_total number NOT NULL, -- previous running total
除了你的限制之外
-- I guess you already have these two constraints
PRIMARY KEY (id),
FOREIGN KEY (parent_id)
REFERENCES parent (id),
CHECK ( allocation >= 0 ),
我们为以前的子关系添加了更多的子关系:
-- this links a child to the previous one
FOREIGN KEY (parent_id, prev_child_no, prev_running_total)
REFERENCES child (parent_id, child_no, running_total),
-- these 2 constraints enforce that there are
UNIQUE (parent_id, child_no), -- maximum 3 children
CHECK (child_no IN (1,2,3)), -- per parent
-- and this exactly 3 children per parent
CHECK ( child_no = 1 AND prev_child_no = 3
OR child_no > 1 AND prev_child_no + 1 = child_no ),
对于运行总数:
-- this enforces that the running total is correct
CHECK ( child_no = 1 AND running_total = allocation
OR child_no > 1 AND running_total = allocation + prev_running_total ),
-- enforce that it never exceeds 100
CHECK ( running_total <= 100 )
) ;
--这强制执行运行总数是正确的
检查(子项编号=1,运行总数=分配
或子项编号>1且运行总数=分配+上一个运行总数),
--强制执行该值不得超过100
检查(不管怎样运行_total,这里有更多的指针..类似的问题陈述数字3真的被修复了吗?parent
表中的每一行在child
表中是否正好有3个相关行?