设为首页 收藏本站
查看: 600|回复: 0

[经验分享] (转)Oracle数据库中违反唯一约束的处理

[复制链接]

尚未签到

发表于 2016-8-4 14:07:23 | 显示全部楼层 |阅读模式
  根据NULL的定义,NULL表示的是未知,因此两个NULL比较的结果既不相等,也不不等,结果仍然是未知。根据这个定义,多个NULL值的存在应该不违反唯一约束。
  实际上Oracle也是如此实现的:
  

SQL> CREATE TABLE T (ID NUMBER);
表已创建。
SQL> ALTER TABLE T ADD UNIQUE (ID);
表已更改。
SQL> INSERT INTO T VALUES (1);
已创建 1 行。
SQL> INSERT INTO T VALUES (1);
INSERT INTO T VALUES (1)
*第 1 行出现错误:
ORA-00001: 违反唯一约束条件 (YANGTK.SYS_C007300)
SQL> INSERT INTO T VALUES (NULL);
已创建 1 行。
SQL> INSERT INTO T VALUES (NULL);
已创建 1 行。
SQL> INSERT INTO T VALUES (NULL);
已创建 1 行。

  
  但是当唯一约束为复合字段时,则情况发生了变化。根据Oracle文档的描述,对于复合字段的唯一约束,不为空字段的值是不能重复的。也就是说,如果两个字段构成了一个唯一约束,其中一个字段为空,那么另一个字段的值不能出现重复。
  

SQL> DROP TABLE T PURGE;
表已删除。
SQL> CREATE TABLE T (ID NUMBER, ID2 NUMBER);
表已创建。
SQL> ALTER TABLE T ADD UNIQUE (ID, ID2);
表已更改。
SQL> INSERT INTO T VALUES (1, 1);
已创建 1 行。
SQL> INSERT INTO T VALUES (1, NULL);
已创建 1 行。
SQL> INSERT INTO T VALUES (2, NULL);
已创建 1 行。
SQL> INSERT INTO T VALUES (1, NULL);
INSERT INTO T VALUES (1, NULL)
*第 1 行出现错误:
ORA-00001: 违反唯一约束条件 (YANGTK.SYS_C007301)
SQL> INSERT INTO T VALUES (NULL, NULL);
已创建 1 行。
SQL> INSERT INTO T VALUES (NULL, NULL);
已创建 1 行。
SQL> INSERT INTO T VALUES (NULL, NULL);
已创建 1 行。

  
  对于全部为NULL的情况,仍然和单字段唯一约束一样,不会造成重复,但是对于部分为NULL的情况,就如上面例子所示,只要其中不为NULL的部分发生了重复,Oracle就认为约束发生了重复。
  而这似乎和NULL的定义有所冲突,第一次看concept的时候一直没有搞明白Oracle为什么这么实现,不过这次再看concept的时候,已经想明白了。
  由于Oracle的唯一约束是依赖索引实现的,而Oracle的BTREE索引又是不存储NULL值的,所以键值全部为NULL的记录不会记录在索引中,因此也就不会违反唯一约束了,而对于部分为NULL的记录,索引是要记录数值的,因此一旦键值中非NULL部分发生了冲突,Oracle就认为违反了的唯一约束。
  Oracle在这里还是选择了自己的方便的方法来实现,而没有完全真正的根据NULL的定义去实现唯一约束。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-252808-1-1.html 上篇帖子: 在oracle中建立自动递增的主键列(转) 下篇帖子: oracle中改变字段在表中的顺序[转]
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表