Oracle:两个条件都为真时的条件非空约束

时间:2018-12-18 16:26:45

标签: sql oracle constraints

我必须修改表以在特定列上创建条件式非空约束,以便如果col1和col2具有值,则它不能为空。

首先,什么是条件非null约束?

第二,能否请您提供有关如何完成此操作的语法?

2 个答案:

答案 0 :(得分:3)

这听起来像是check约束:

alter table t add constraint chk_t_specific
    check ( (col1 is null) or (col2 is null) or (specific is not null) );

这也可以写成:

alter table t add constraint chk_t_specific
    check (not ( (col1 is not null) and 
                 (col2 is not null) and
                 (specific is null)
               ) 
          );

如果这样可以帮助您更好地遵循逻辑。

仅在以下情况下,此结果为false:

  • col1不为空(即col1确实有一个值)
  • col2不为空(即col2确实有一个值)
  • specific为空

这是OP想要过滤掉的确切条件。

在现有表上,您可以查看哪些行违反了约束:

select *
from t
where col1 is not null and col2 is not null and specific is null;

如果任何行违反了约束,则需要在添加约束之前对其进行修复。

答案 1 :(得分:3)

您需要检查的谓词是

if (col1 is not null and col2 is not null) then specific is not null

谓词if A then B可以写为not A or B

请注意,优先级为(not A) or B,请参见讨论here

所以您得到:

alter table spec add constraint my_spec
check (not (col1 is not null and col2 is not null) or specific is not null);

如果col1或col2为空,则spnificable可为空

insert into spec(col1,col2,specific) values(null,null,null);
insert into spec(col1,col2,specific) values(1,null,null);
insert into spec(col1,col2,specific) values(null,1,null);

如果col1和col2都是在NOT NULL中定义的,则为

insert into spec(col1,col2,specific) values(1,1,1);
insert into spec(col1,col2,specific) values(1,1,null);
-- ORA-02290: check constraint (REPORTER.MY_SPEC) violated

在现有表上,仅当现有数据完全满足验证条件时,您才可以添加此check,否则您将收到此异常

 ORA-02293: cannot validate (OWNER.MY_SPEC) - check constraint violated

要查找违反新规则的行,只需查询

 select * from spec
 where NOT (not (col1 is not null and col2 is not null) or specific is not null);

您必须删除这些行,或者将specific设置为非NULL值,或者将col1或col2设置为NULL。

或者,您可以使用NOVALIDATE选项启用约束,这可以容忍现有的违规行为,但可以强制新更改遵循约束。

alter table spec add constraint my_spec
check (not (col1 is not null and col2 is not null) or specific is not null)
enable novalidate;