首页 > 解决方案 > SQL 约束检查值存在于同一张表的另一列中

问题描述

我有一张表,其中每一行都是一项任务。每个任务都有一个父级(即实例化它的任务),或者一个空父级(任务在时间开始时发生)。我想给父列添加一个约束,使它只能取一个空值或任务列中已经存在的值,并且不等于它自己的任务。

tasks
=====
task (PK) | description | duration | parent
----------+-------------+----------+--------
ABC-123   | Foo         |       10 | Null     <--- OK
DEF-456   | Bar         |        8 | ABC-123  <--- OK  
GHI-789   | Baz         |       12 | ABC-123  <--- OK
JKL-987   | Boz         |        7 | Null     <--- OK
MNO-654   | Foz         |       88 | GHI-789  <--- OK
PQR-321   | Faz         |        6 | ZZZ-999  <--- Not OK; parent doesn't exist
STU-123   | Fez         |        5 | STU-123  <--- Not OK; can't be its own parent

我怎样才能做到这一点?我想添加一个约束,例如: CONSTRAINT ck_parent_valid CHECK parent <> task AND parent NOT IN task ..但上面显然不起作用,因为我需要同时引用当前行中的任务和整个任务列。

标签: sql

解决方案


一种方法是向表中添加外键约束,RDBMS 会自动检查它,您也可以自动设置cascade updatecascade delete完成更改而无需任何编码。如下所示:

ALTER TABLE tasks 
ADD CONSTRAINT FK_tasksParent
FOREIGN KEY (parent) REFERENCES tasks(task);

推荐阅读