我必须修改表以在特定列上创建条件式非空约束,以便如果col1和col2具有值,则它不能为空。
首先,什么是条件非null约束?
第二,能否请您提供有关如何完成此操作的语法?
答案 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;