日期:2014-05-16  浏览次数:20457 次

oracle约束学习(1)unique和check

    有人说,没有索引, 拿什么来保证约束?姑且不论这话的对错,但约束的实现(除了not null),很多都是通过索引来快速定位约束的地方。unique约束会自动建立索引,pk也是。也因此,约束的很多问题总是和索引缠绵一起。

 

    相关视图:

              dba_constraints
              dba_cons_columns

 

    not null约束比较特别点。not null的索引类型和check约束一样,都是C。只有not null这种约束才会被继承,记住这一点,在复制表时,别忘了加约束、索引等。

 

    unique  约束
    延迟验证属性:deferrable/not deferrable, Deferred/immediate  

    延迟约束在提交的时候才进行校验,大多数是这样的。

    not deferrable:不提交也检查,这是缺省值。

SQL> select * from hr.t1;

        ID NAME
---------- ----------------------------------------
         1 d
         2 b

SQL> conn hr/hr
已连接。
SQL> alter table t1 add constraint t1_u_1 unique(id); -- 默认情况下是not deferrable & immediate

表已更改。

SQL> insert into t1 values(1,'c');
insert into t1 values(1,'c')
*
第 1 行出现错误:
ORA-00001: 违反唯一约束条件 (HR.T1_U_1)


SQL> alter table t1 drop constraint t1_u_1 cascade;

表已更改。

SQL> alter table t1 add constraint t1_u_2 unique(id) deferrable; --deferrable & immediate

表已更改。
SQL> select * from t1;

        ID NAME
---------- ----------------------------------------
         1 d
         2 b

SQL> insert into t1 values(1,'c');
insert into t1 values(1,'c')
*
第 1 行出现错误:
ORA-00001: 违反唯一约束条件 (HR.T1_U_2)


    为什么延迟还还报错呢?延迟性约束,索引必须非唯一。enable novalidate也必须是非唯一索引。然而,我们在建unique约束的时候,oracle会隐士的先创建一个唯一性索引,而且索引的名字和约束的名字是一样的。再来建立约束,除非这个列本来有一个约束。

SQL> alter table t1 add constraint t1_u_6 unique(id);

表已更改。

SQL> select index_name,uniqueness from user_indexes ;

INDEX_NAME                                                   UNIQUENESS
------------------------ ------------------
T1_U_6                                                       UNIQUE


   

   

SQL> alter table t1 add constraint t1_u_3 unique(id) deferrable; --deferrable & immediate

表已更改。

SQL> select * from t1;

        ID NAME
---------- ----------------------------------------
         1 d
         2 b

SQL> insert into t1 values(1,'c');
insert into t1 values(1,'c')
*
第 1 行出现错误:
ORA-00001: 违反唯一约束条件 (HR.T1_U_3)


SQL> alter table t1 drop constraint t1_u_3 cascade;

表已更改。

SQL> drop index t1_index;

索引已删除。

SQL> create unique index t1_index on t1(id);

索引已创建。

SQL> select index_name,uniqueness from user_indexes;

INDEX_NAME                                                   UNIQUENESS
------------------------ ------------------
T1_INDEX                                                     UNIQUE

SQL> alter table t1 add constraint t1_u_4 unique(id) deferrable;
alter table t1 add constraint t1_u_4 unique(id) deferrable
*
第 1 行出现错误:
ORA-01408: 此列列表已索引

SQL> drop index t1_index;

索引已删除。

SQL> alter table t1 drop constraint t1_u_4 cascade;
alter table t1 drop constraint t1_u_4 cascade
                               *
第 1 行出现错误:
ORA-02443: 无法删除约束条件 - 不存在的约束条件
SQL> alter table t1 add constraint t1_u_5 unique(id) initially deferred deferrable; --若是not deferrable,则只能跟immediate

表已更改。

SQL> select * fr