一、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
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/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/29515435/viewspace-1127656/