如何检查表中是否仅存在一个给定列值的组合

时间:2018-09-04 21:49:35

标签: oracle constraints unique

我有一个表,该表具有3列子级,父级和祖父母级。子列是主键。多个孩子可以向同一个父母报告。

当前,我的表有4个孩子向同一父报告,因此我在表中有4行。由于所有四个孩子的父母都是相同的,所以我希望祖父母也应该相同。

但是对于某些记录,“祖父母”的价值观是不同的,这是一个问题,我想添加一个约束条件或防止这种情况发生的方法。

例如,我的表格如下所示

Child | Parent | GrandParent |
10001 | 101    | 700         |
10002 | 101    | 700         |
10003 | 101    | 701         |
10004 | 101    | 700         |

第4个孩子10003向父101报告,但是grandParent不同,我想防止它发生。

Parent / GrandParent组合上通常的唯一键约束将不起作用,因为这两列可以具有重复的值。我不能为三列添加约束,因为它不会阻止上述情况的发生。

能否让我知道如何实现这一目标?我正在使用Oracle 12c。

1 个答案:

答案 0 :(得分:0)

选项1。

如评论中所述,祖父母栏不是必需的。父-祖父母关系即与子-父母相同。

赞:

select a.child, a.parent, b.parent 
from parentchild a
,    parentchild b 
where b.child = a.parent

选项2。

但是,如果您坚持要采用这种表布局,则可以在表上定义一个插入或更新之前触发器,该触发器将检查表中是否存在与相同父级相同但与<强>不同的祖父母。如果找到这样的行,则触发器应该失败并标记错误,否则可以插入或更新记录。

触发器的示例代码:

create trigger parentchild_iu
before insert or update
on parentchild for each row
declare
v_count number;
begin
   select count(*) into v_count
   from   parentchild p
   where  p.parent = :new.parent
   and    p.grandparent != :new.grandparent;

   if v_count != 0 then
      raise_application_error("Parent/Grandparent combination invalid.");
   end if;
end;

选项3。

作为第三个选项,您可以将表分为两个表:childparent和parentgranparent,并具有以下查询:

select a.child, a.parent, b.grandparent
from   childparent a
,      parentgrandparent b
where  a.parent = b.parent;

并且在两个表中都为两列定义了唯一的键。