約束constraint的 enable/disable novalidate總結

轉自:http://blog.chinaunix.net/uid-20274021-id-1969663.html


我們知道對constraint的開啓和關閉共有四種:enable validate;enable novalidate;disable validate;disable novalidate。
enable validate/disable validate 這兩種沒什麼說的。
enable novalidate/disable novalidate 分別表示開啓時不檢查已存在數據/不檢查今後的數據。
 
今天主要對enable novalidate/disable novalidate 做個簡單測試。
 
SQL> create table pk1(id number(2),name varchar2(8));
表已創建。
SQL> insert into pk1 values(1,'abc');
已創建 1 行。
SQL> alter table pk1 add constraint pk_pk1 primary key(id);   --設置主鍵約束。
表已更改。
SQL> create table fr1(id number(2),name varchar2(8));
表已創建。
SQL> insert into fr1 values(1,'abc');
已創建 1 行。
SQL>  alter table fr1 add constraint fk_fr1 foreign key(id) references pk1(id);
表已更改。
 
--設置外鍵。

測試外鍵下使用enable novalidate/disable novalidate的情況
 
SQL> insert into fr1 values(2,'aaa');
insert into fr1 values(2,'aaa')
*
第 1 行出現錯誤:
ORA-02291: 違反完整約束條件 (SYS.FK_FR1) - 未找到父項關鍵字
 
SQL> alter table fr1 disable novalidate constraint fk_fr1;
表已更改。
 
SQL> insert into fr1 values(2,'aaa');
已創建 1 行。
 
SQL> select * from fr1;
        ID NAME
---------- --------
         1 abc
         2 aaa
 
SQL> alter table fr1 enable validate constraint fk_fr1;
alter table fr1 enable validate constraint fk_fr1
                                           *
第 1 行出現錯誤:
ORA-02298: 無法驗證 (SYS.FK_FR1) - 未找到父項關鍵字

SQL> alter table fr1 enable novalidate constraint fk_fr1;
表已更改。
 
--從上面測試結果可見enable novalidate和disable novalidate在外鍵約束下使用是好用的。
 
 
測試主鍵下使用enable novalidate/disable novalidate的情況
 
SQL> select * from pk1;
        ID NAME
---------- --------
         1 abc
 
SQL>  alter table pk1 disable novalidate primary key;
 alter table pk1 disable novalidate primary key
*
第 1 行出現錯誤:
ORA-02297: 無法禁用約束條件 (SYS.PK_PK1) - 存在相關性
 
SQL> alter table fr1 disable validate constraint fk_fr1;
表已更改。
 
SQL> alter table pk1 disable novalidate primary key;
表已更改。
 
SQL> insert into pk1 values(1,'ccc');
已創建 1 行。
 
SQL> select * from pk1;
        ID NAME
---------- --------
         1 abc
         1 ccc
 
SQL> alter table pk1  enable novalidate primary key;
alter table pk1  enable novalidate primary key
*
第 1 行出現錯誤:
ORA-02437: 無法驗證 (SYS.PK_PK1) - 違反主鍵
 
SQL> select INDEX_NAME,TABLE_NAME,TABLE_OWNER from user_indexes where index_name
='PK_PK1';
未選定行
 
--主鍵對應的索引PK_PK1已經不在了。
 
SQL> create index cc on pk1(id);
索引已創建。
 
SQL> alter table pk1 enable novalidate primary key;
表已更改。
--OK了。
 
--從上面的測試結果看出:novalidate在非主鍵,唯一鍵時可以正常工作。在對主鍵,唯一鍵使用時需要先創建相關索引,再使用novalidate。Primary and unique keys must use nonunique indexes。
 
舉一個使用novalidate的案例:
 
給一個有數據的表增加一個非空的列。要求:需要在該表上增加一個字段status,但該字段不能爲空,歷史數據可以爲空。最後將歷史數據的該新加字段統一置爲1
 
SQL> desc pk1;
 名稱                                      是否爲空? 類型
 ----------------------------------------- -------- -------------
 ID                                        NOT NULL NUMBER(2)
 NAME                                               VARCHAR2(8)
 
SQL> select * from pk1;
        ID NAME
---------- --------
         1 abc
         2 cba
 
SQL> alter table pk1 add status number(1);
表已更改。
 
SQL> alter table pk1 modify status not null enable novalidate;
表已更改。
 
SQL> select * from pk1;
        ID NAME         STATUS
---------- -------- ----------
         1 abc
         2 cba
 
SQL> update pk1 set status=1;
已更新2行。
 
SQL> commit;
提交完成。
 
SQL> select * from pk1;
        ID NAME         STATUS
---------- -------- ----------
         1 abc               1
         2 cba               1

SQL> insert into pk1 values(3,'bca',null);
insert into pk1 values(3,'bca',null)
                               *
第 1 行出現錯誤:
ORA-01400: 無法將 NULL 插入 ("SYS"."PK1"."STATUS")

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章