ITPub博客

首页 > 数据库 > Oracle > 约束的状态和状态的切换

约束的状态和状态的切换

原创 Oracle 作者:dba_manganese 时间:2014-03-23 14:42:12 0 删除 编辑
一、Oracle约束的几种状态
Oracle的约束存在下述几种状态:ENABLE/DISABLE、VALIDATE
/NOVALIDATE,下面分别说明这几种状态的含义:
ENABLE:启用约束
DISABLE:禁用约束
VALIDATE:验证对象内的记录是否满足约束条件
NOVALIDATE:不验证对象内的记录是否满足约束条件

二、Oracle约束的状态组合

这几种状态之间的组合情况说明如下:
ENABLE VALIDATE:启用约束,并且检查对象内记录是否满足约束条件,如不满足,将返回错误提示,需更新或删除违反约束的数据。
ENABLE NOVALIDATE:启用约束,不检查对象内记录是否满足约束条件,对于对象内违反约束的数据采取的是“既往不咎”的态度
DISABLE VALIDATE:禁用约束,但是要检查对象内记录是否满足约束条件,如不满足,将返回错误提示,需更新或删除违反约束的数据。
DISABLE NOVALIDATE
:禁用约束,检查对象内记录是否满足约束条件。

三、实验记录
通过一个实验来验证上述论断:
SQL> conn eric/eric
Connected.

SQL> create table t1 (id number,name varchar(10));
Table created.                                                             //创建测试用表t1

SQL> alter table t1 add constraint pk_t1 primary key (id);
Table altered.    
                                                                                //在测试用表上创建一个主键约束pk_t1
SQL> alter table t1 disable novalidate constraint pk_t1;
Table altered.  
                                                                               //修改约束状态为不启用,不验证状态
SQL> insert into t1 values (1,'alex');
1 row created.

SQL> insert into t1 values (1,'bob');
1 row created.
                                                                              //此处插入的数据存在违反约束的情形,但是由于禁用了约束,所以不影响插入操作
SQL> commit;
Commit complete.

SQL> alter table t1 enable novalidate constraint pk_t1;
alter table t1 enable novalidate constraint pk_t1
*
ERROR at line 1:
ORA-02437: cannot validate (ERIC.PK_T1) - primary key violated               //切换约束状态为启用,不验证状态,但是提示错误ORA-02437

对于上述错误,感觉到很疑惑,难道文档中的说明是错误吗?在网上搜索了半天也没有结论,无奈之下在pub上发出了“处女贴”。经好心人士提点,终于明白了原因:使用ENABLE选项启用约束时会在对象上创建一个唯一索引,而在一开始禁用了约束之后,在表内插入了两条ID为1的记录(违反了唯一约束),所以导致上述的错误发生!!!为此特地验证了一番,情况果然如此。过程如下:

SQL> delete from t1 where name='bob';
1 row deleted.                                                                                 //删除违反约束条件的数据

SQL> commit;
Commit complete.

SQL> alter table t1 enable novalidate constraint pk_t1;
Table altered.                                                                                 //启用约束OK

SQL> select index_name,index_type,uniqueness from user_indexes where table_name='T1';
INDEX_NAME                     INDEX_TYPE                  UNIQUENES
------------------------------ --------------------------- ---------
PK_T1                          NORMAL                      UNIQUE             //果然是默认创建了一个名为pk_t1的唯一索引

在了解了问题出现的前因后果之后,将对象上的主键约束改为检查约束,继续按预先设想进行实验:

SQL> create table t2 (a int);
Table created.

SQL> alter table t2 add constraint ck_t2 check (a>10);
Table altered.

SQL> alter table t2 disable novalidate constraint ck_t2;
Table altered.

SQL> insert into t2 values (1);
1 row created.

SQL> insert into t2 values (2);
1 row created.

SQL> commit;
Commit complete.

SQL> alter table t2 enable novalidate constraint ck_t2;
Table altered.                                                                        //这时约束的状态切换就OK了,启用约束,但是不验证表内已有的数据是否违反约束。

SQL> insert into t2 values (5);
insert into t2 values (5)
*
ERROR at line 1:
ORA-02290: check constraint (ERIC.CK_T2) violated                   //在启用约束后,就不能在向表里插入违反约束的记录了(a>10)

SQL> alter table t2 enable validate constraint ck_t2;
alter table t2 enable validate constraint ck_t2                            //启用约束并且验证表内的数据是否违反约束时,出现错误提示了,需要手工去处理。
                                          *
ERROR at line 1:
ORA-02293: cannot validate (ERIC.CK_T2) - check constraint violated 


来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/29515435/viewspace-1127656/,如需转载,请注明出处,否则将追究法律责任。

下一篇: Oracle表的压缩
请登录后发表评论 登录
全部评论

注册时间:2014-03-02

  • 博文量
    13
  • 访问量
    174846