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个相关行?