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

Posted

技术标签:

【中文标题】Oracle:两个条件都为真时的条件非空约束【英文标题】:Oracle: Conditional not-null constraint when both conditions are true 【发布时间】:2018-12-18 16:26:45 【问题描述】:

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

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

其次,您能否提供一个有关如何完成此类事情的语法?

【问题讨论】:

【参考方案1】:

你需要检查的谓词是

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 为空,则特定为空

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 中定义为 secific

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;

【讨论】:

我尝试执行alter命令但遇到了以下错误an alter table operation tried to validate a check constraint to populated table that had nocomplying values. @samg 为您的观点添加了提示,您必须在启用约束之前清理数据。 或者在添加约束之前先从表中删除违规【参考方案2】:

这听起来像是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)
               ) 
          );

如果这有助于你更好地遵循逻辑。

只有在以下条件下才会评估为假:

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

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

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

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

如果有任何行违反了约束,您需要在添加约束之前修复它们。

【讨论】:

不确定检查是如何工作的。但是如果col1col2 不为空,则看起来specific 不能为空 同意@JuanCarlosOropeza,如果col1 AND col2 有值(非空),specific 不能为空。 是的,这很有帮助 嗨@Gordon Linoff,感谢您的详细回答。如果col1col2 为空会发生什么?那样的话,应该没有问题对吧? @samg 。 . .如果col1col2NULL,则check 返回“true”并通过。

以上是关于Oracle:两个条件都为真时的条件非空约束的主要内容,如果未能解决你的问题,请参考以下文章

使用动态名称记录条件为真时的变量值

使用具有不同分隔符的 sed 查找特定条件为真时的 Bash

Sql 条件非空约束

SHELL IF条件判断,判断条件

shell 条件判断

shell条件判断