Oracle主键约束自动建立索引问题

2014-11-24 17:54:53 · 作者: · 浏览: 0

SQL> insert into t values(1,2);

SQL> insert into t values(3,4);

SQL> commit;



SQL> select * from t;

I V
---------- ----------
1 2
3 4
现在表中有两条记录,然后给它插主键为空或相同的值。


SQL> insert into t values('',10);

ERROR at line 1: ORA-01400: cannot insert NULL into ("Y"."T"."I")

SQL> insert into t values(1,10);
insert into t values(1,10)
*
ERROR at line 1:
ORA-00001: unique constraint (SYS.PK_I) violated

可以看到全部报错,此时主键不能为空或重复

查看是否建立索引

SQL> select index_name from user_indexes;

INDEX_NAME

------------------------------

PK_I

把约束关闭再次做同样的操用

SQL> alter table t disable novalidate constraint pk_i;

Table altered.

SQL> insert into t values('',10);

1 row created.

SQL> insert into t values(1,10);

1 row created.

SQL> commit;

Commit complete.


SQL> select * from t;


I V
---------- ----------
1 2
3 4
1 10

10

SQL> select index_name from user_indexes;

no rows selected

可见当把约束关闭后就可以何意给表插数据了,而具索引也自动删除了。

现在激活约束

SQL> alter table t enable validate constraint pk_i;

alter table t enable validate constraint pk_i ERROR at line 1: ORA-02437: cannot validate (SYS.PK_I) - primary key violated

因为表中主键有相同的值所以不能恢复到enable validate状态了


再次测试回复到enable novalidate

SQL> alter table t enable novalidate constraint pk_i;

alter table t enable validate constraint pk_i ERROR at line 1: ORA-02437: cannot validate (SYS.PK_I) - primary key violated

也失败了,enable novalidate不检查旧数据所以应该还能恢复到enable novalidate,但为什么不行呢?因为在执行命令时,会产生唯一性索引(对pk_i),但对表中pk_i列已经有了重复的值,无法建立唯一性索引。


要想恢复到enable novalidate必须建立主键索引(关闭约束时自动删除的那个索引,非唯一)如下:

SQL> create index pk_i on t(i);

Index created.

索引的默认类型是非唯一,非压缩,非反向键B*树索引。


然后恢复到enable disvalidate,以后再插数据不能为空,主键也不能重复了.

SQL> alter table t enable novalidate constraint pk_i;

Table altered.

SQL> insert into t values(1,14);

insert into t values(1,14) ERROR at line 1: ORA-00001: unique constraint (SYS.PK_I) violated