Oracle約束的關鍵字Enable/Disable/Validate/Novalidate
enable/disable對未來的資料有約束/無約束。 validate/novalidate對已有的資料有約束/無約束。
約束有如下四種狀態
(1)ENABLEVALIDATE:約束在建立時,預設就是此狀態。此狀態會“檢查表中原有行和新插入的行”。
(2)ENABLENOVALIDATE:不能輸入違反約束的新資料。但是,在建立約束時,並不檢查表中原有行。
(3)DISABLEVALIDATE:檢查表中原有行是否違反約束,表中可以插入違反約束的行。
(4)DISABLENOVALIDATE:約束處於禁用狀態,且此狀態檢查表中原有資料是否違反約束.
參考部落格:
註釋:
2、
Enable/Disable和Validate/Novalidate這兩組關鍵字修飾的都是同一個物件,即constraint這種型別的物件。
在修飾同一個物件時,兩組關鍵字間是並列關係,即Enable/Disable這組關鍵字作用在未來的資料(即表上插入/更新/刪除的資料)上,而Validate/Novalidate這組關鍵字作用在表上已有的資料上。
上圖中,?表示不受約束條件限制,√表示受約束條件限制。
這裡要說說×表示什麼意思?
disable和validate組合在一起時,由於disable是表示對未來的資料不受約束條件限制,即對DML操作修改過的資料都不進行約束條件檢查。現在假設一條不符合約束條件的資料插入了表中,而Validate/Novalidate這組關鍵字是每次表中的資料有變化時進行一次約束條件檢查,故而當Validate在該條不符合約束條件的資料插入了表後進行了一次約束條件檢查,發現該資料不符合約束條件,就會報錯。由此看出disable和validate組合在一起時,DML操作修改的資料存放在表中有可能會不符合約束條件,所以oracle設計人員就規定disable和validate組合在一起時不允許進行DML操作對該表。所以,X表示不允許執行DML操作的意思。所以,如果你不想某個表被DML操作
1組合特性說明
Enable/Disable和Validate/Novalidate這兩組關鍵字修飾的都是同一個物件,即constraint這種型別的物件。
Validate的作用: 確保已有資料符合約束;
Novalidate的作用:不必考慮已有資料是否符合約束。
由此可以看出,
Validate和Novalidate的不同點在於表中已有資料的作用上:
Validate驗證已有資料是否符合約束;Novalidate不必考慮已有資料是否符合約束。
Validate和Novalidate的相同點在於表上插入/更新/刪除的資料的作用上:
對於表上插入/更新/刪除的資料,兩者都會確保這些資料符合約束。
在修飾同一個物件時,兩組關鍵字間不是並列關係,而是上下從屬關係,即Enable/Disable這組關鍵字從屬於Validate/Novalidate這組關鍵字。而且,在Validate/Novalidate這組關鍵字所作用的兩個範圍:表中已有資料和表上插入/更新/刪除的資料中,Enable/Disable這組關鍵字只能影響一個範圍,即表上插入/更新/刪除的資料。
Validate |
Novalidate |
|||
已有記錄 |
新增/刪除記錄 |
已有記錄 |
新增/刪除記錄 |
|
Enable |
Yes(表示需要受到約束條件限制) |
Yes |
No |
Yes |
Disable |
Yes |
No |
No |
No |
從上表可以看出,
對於帶有Validate的約束(constraint,名詞),無論Enable還是Disable該約束,該約束對錶中已有記錄都是會驗證這些表中已有記錄是否符合約束條件的,而對於帶有noValidate的約束(constraint,名詞),無論Enable還是Disable該約束,該約束對錶中已有記錄都是不會驗證這些表中已有記錄是否符合約束條件的。
對於表上插入/更新/刪除的資料,enable帶有Validate的約束或是帶有noValidate的約束,則都會驗證這些表上插入/更新/刪除的資料是否符合約束條件的;反之,Disable帶有Validate的約束或是帶有noValidate的約束,則都不會驗證這些表上插入/更新/刪除的資料是否符合約束條件的。
例如,alter table test disable validate constraint ck_id,表示禁用(Disable)帶有驗證(Validate)屬性的約束ck_id,其中
Disable作為支配約束這個物件的動詞來翻譯,而Validate作為修飾約束這個物件的形容詞來翻譯。
註釋:
Validate確保已有資料符合約束;
Novalidate不必考慮已有資料是否符合約束。
除非Novalidate被指定,Enable預設Validate;
除非Validate被指定,Disable預設Novalidate。
Enable Validate與Enable相同,表示檢查已有記錄和新增記錄(即表上插入/更新/刪除的資料),確保都符合約束;
Enable Novalidate,表示允許已有記錄不必滿足約束條件,但新增/修改的記錄(即表上插入/更新/刪除的資料)必須滿足;
Disable Validate,表示禁用(帶有Validate的)約束,刪除約束上的索引(??),不允許修改任何被約束的記錄(即表上插入/更新/刪除的資料??);
Disable Novalidate與Disable相同,表示禁用(帶有noValidate的)禁用約束,刪除約束上的索引(??),且允許修改被約束的記錄(即表上插入/更新/刪除的資料??)。
2建表
SQL> create table test(id int, name varchar2(10));
Table created
SQL> alter table test add constraint ck_id check(id > 10);
Table altered
3測試1: Enable Validate
SQL> alter table test Enable validate constraint ck_id;
Table altered
SQL> insert into test values(5, 'Oracle');
insert into test values(5, 'Oracle')
ORA-02290:違反檢查約束條件 (MYHR.CK_ID)
SQL> insert into test values(17,'ERP');
1 row inserted
SQL> commit;
Commit complete
4測試2: Enable Novalidate
SQL> alter table test disable constraint ck_id;
Table altered
SQL> insert into test values(5, 'Oracle');
1 row inserted
SQL> commit;
Commit complete
SQL> select * from test;
ID NAME
----------- ----------
17 ERP
5 Oracle
SQL> alter table test enable novalidate constraint ck_id;
Table altered
SQL> insert into test values(32, 'SAP');
1 row inserted
SQL> insert into test values(3, 'Linux');
insert into test values(3, 'Linux')
ORA-02290:違反檢查約束條件 (MYHR.CK_ID)
SQL> commit;
Commit complete
5測試3: Disable Validate
SQL> delete from test where id < 10;
1 row deleted
SQL> commit;
Commit complete
SQL> alter table test disable validate constraint ck_id;
Table altered
SQL> select * from test;
ID NAME
------------- ----------
17 ERP
32 SAP
SQL> update test set name = 'Change' where id = 17;
update test set name = 'Change' where id = 17
ORA-25128:不能對帶有禁用和驗證約束條件 (MYHR.CK_ID)的表進行插入/更新/刪除
ORA-25128:no insert/update/delete on table with constraint disabled and validated
6測試4: Disable Novalidate
SQL> alter table test disable novalidate constraint ck_id;
Table altered
SQL> insert into test values(2, 'Linux');
1 row inserted
SQL> insert into test values(13, 'Windows');
1 row inserted
SQL> update test set name = 'Change' where id = 17;
1 row updated
SQL> commit;
Commit complete
SQL> select * from test;
ID NAME
---------- ----------
17 Change
13 Windows
32 SAP
2 Linux