2011-03-27 54 views
17

如果我有PostgreSQL中表:添加在PostgreSQL里的一出的两不空约束

create table Education ( 
    id     integer references Profiles(id), 
    finished   YearValue not null, 
    started    YearValue, 
    qualification  text, 
    schoolName   text, 
    studiedAt   integer references Organizations(id), 
    primary key (id) 
); 

我需要做出约束,使得无论是schoolNamestudiedAt需要不能为空(其中一个必须有信息)。

我该怎么做?

回答

26

您可以使用check constraint

constraint chk_education check (schoolName is not null or studiedAt is not null) 

从手册:

检查约束是最通用的限制类型。它允许您指定某个列中的值必须满足布尔(真值)表达式。

编辑:另类遵守Pithyless'解释:

constraint chk_education check ((schoolName is not null and studiedAt is null) or (schoolName is null and studiedAt is not null)) 
+1

这张支票并不防范学校名称和研究设置,我认为OP也考虑过了。 – pithyless 2011-07-26 18:17:07

+0

该问题要求至少强调'schoolName'和'studyingAt'包含一些信息的不变量。我已经添加了符合您评论的约束变体,但我不同意这个问题的解释。 – 2011-07-26 19:47:59

+2

这有点迟了,但是这是一个XOR约束,所以你可以把它表示为'CHECK((schoolName IS NULL)<>(studyingAt IS NULL))' – norcalli 2017-08-16 22:11:02

0

您也可以使用更新的触发器,并插入检查规则是允许数据到表之前紧随其后。当检查约束需要更复杂的逻辑时,通常会使用这种类型的方法。

+1

告诫:通常最好不要执行约束而不是求助于trigger – 2011-03-27 20:07:34

+0

我不会说尽量不使用触发器来强制执行约束,我可能会说相反。使用触发器时,请始终记住性能并明智地使用它们。不要将它们用于它。测试他们为您的具体需求,如果它允许您满足您的需求去为它。使用触发器并不存在固有的弊端。这是盒子里的另一个工具。 – Kuberchaun 2011-03-28 11:36:20

+0

我想这已经[辩论之前](http://stackoverflow.com/questions/460316/are-database-triggers-evil)。我对他们的抱怨是,他们没有对现有的数据执行规则,而且他们经常围绕着他们来获取数据,而没有他们的解雇(例如Oracle的SQL * loader)。鉴于此,具有明确定义的交易的api不会带来任何副作用(并且有更多的好处) – 2011-03-28 11:52:02