Oracle数据库约束中的NULL的处理

Oracle数据库约束中的NULL的处理,第1张

Oracle数据库约束中的NULL的处理,第2张

根据NULL的定义,NULL表示未知,所以两个NULL比较的结果既不相等也不相等,结果还是未知的。根据这个定义,多个空值的存在不应该违反约束。
其实Oracle是这样实现的:
SQL > Create Tablet (ID号);
表已经创建。
SQL > ALTER TABLE T ADD UNIQUE(ID);
该表已被更改。
SQL >插入T值(1);
已创建1行。
SQL >插入T值(1);
insert into t values(1)
*第1行错误:
ORA-00001:违反约束(yangtk . sys _ c 007300)
SQL > insert into t values(null);
已创建1行。
SQL >插入T值(NULL);
已创建1行。
SQL >插入T值(NULL);
已创建1行。
但是当约束是复合字段时,情况就不同了。根据Oracle文档的描述,对于复合字段的约束,除空字段以外的值不能重复。也就是说,如果两个字段构成一个约束,其中一个是空,则另一个字段的值不能重复。
SQL >删除表T清除;
该表已被删除。
SQL >创建表T (ID号,ID2号);
表已经创建。
SQL > ALTER TABLE T ADD UNIQUE(ID,ID2);
该表已被更改。SQL> INSERT INTO T值(1,1);
已创建1行。
SQL> INSERT INTO T值(1,NULL);
已创建1行。
SQL> INSERT INTO T值(2,NULL);
已创建1行。
SQL> INSERT INTO T值(1,NULL);
insert into t values (1,null)
*第1行出错:
ORA-00001:违反约束(yangtk . sys _ c 007301)
SQL > insert into t values(null,null
已创建1行。
SQL> INSERT INTO T值(NULL,NULL);
已创建1行。
SQL> INSERT INTO T值(NULL,NULL);
已创建1行。
对于所有的null情况,它仍然与单字段约束相同,但是对于某些NULL情况,如上例所示,只要非NULL部分重复,Oracle就认为该约束是重复的。
而这似乎与NULL的定义相冲突。当我第一次看concept的时候,我一直不明白Oracle为什么要这么实现。不过,这次再看《概念》的时候,我已经想通了。
因为Oracle的约束是通过索引实现的,而Oracle的BTREE索引不存储空值,所以索引中不会记录所有键值都为空的记录,所以不会违反约束。对于一些具有空值的记录,索引将记录数值,因此一旦键值的非空部分发生冲突,Oracle将认为违反了约束。
Oracle在这里选择了自己方便的方法实现约束,而不是完全按照NULL的定义来实现约束。

位律师回复
DABAN RP主题是一个优秀的主题,极致后台体验,无插件,集成会员系统
白度搜_经验知识百科全书 » Oracle数据库约束中的NULL的处理

0条评论

发表评论

提供最优质的资源集合

立即查看 了解详情