2

我的问题是关于检查约束,正常的语法是:

ALTER TABLE barracks
ADD CONSTRAINT chk_barracks CHECK( status IN('Destroyed', 'constructed'))  

这意味着列状态应该被破坏或构造。

在下面我指定营房不接受空值

 ALTER TABLE barracks
 ADD CONSTRAINT chk_barracks CHECK(status IN('Destroyed', 'constructed')
    AND status IS NOT NULL) 

现在我添加了列colour。我想指定如果 barracks构造的,那么colour应该只是RED并且列STATUS应该是NOT NULL

如果军营被摧毁

然后colour应该是BLACK并且列STATUS应该是NULL

所以这是我写的检查约束:

 ALTER TABLE barracks
 ADD CONSTRAINT chk_barracks CHECK( ((status IN ('Destroyed', 'constructed')
         AND status IS NOT NULL) 
         AND (color IN('RED') )) 
    OR (( status IN('Destroyed', 'constructed') 
         AND status IS NULL) 
         AND (color IN('BLACK') )))  

如果颜色为红色,我仍然可以插入NULL到列中的问题status。如何以检查我上面提到的条件的方式解决这个约束?

4

1 回答 1

3

使用 CHECK 约束来强制执行诸如“Destroyed”、“constructed”之类的值是个坏主意。改为使用查找表的外键。除此之外,这将防止逻辑上的荒谬,例如:

( status IN('Destroyed', 'constructed') 
         AND status IS NULL) 

然后,您还有一个更简单的检查条件:

( ( status is not null and color = 'RED') 
   or ( status is null and color = 'BLACK') 

至少您应该有两个单独的检查约束:一个验证 STATUS 的值,另一个验证 COLOR 与是否填充 STATUS 之间的关系。


更多关于外键。像这样创建一个表:

 create table barracks_statuses
     ( status varchar2 (15) not null
       , constraint bsts_pk primary key (status)
 organization index;

 insert into barracks_statuses values ( 'Destroyed');
 insert into barracks_statuses values ( 'constructed');

然后像这样强制执行外键:

alter table barracks
    add constraint barr_bsts_fk foreign key (status)
        references (status);

这种方法很有用,因为它提供了更大的灵活性。您添加一个新状态,例如“已计划”,或者仅使用 DML 修复“已构建”中的错字,或者重写一些复杂的检查约束。

于 2013-06-21T15:32:00.480 回答