一、Oracle約束的狀態(tài)
疏勒ssl適用于網(wǎng)站、小程序/APP、API接口等需要進(jìn)行數(shù)據(jù)傳輸應(yīng)用場(chǎng)景,ssl證書(shū)未來(lái)市場(chǎng)廣闊!成為創(chuàng)新互聯(lián)建站的ssl證書(shū)銷(xiāo)售渠道,可以享受市場(chǎng)價(jià)格4-6折優(yōu)惠!如果有意向歡迎電話(huà)聯(lián)系或者加微信:028-86922220(備注:SSL證書(shū)合作)期待與您的合作!
Oracle完整性約束的狀態(tài)有4種,分別是ENABLE、DISABLE、VALIDATE、NOVALIDATE。
ENABLE 表示Oracle將檢查要插入或更新的數(shù)據(jù)庫(kù)中的數(shù)據(jù)是否符合約束;
DISABLE 表示表中可以存放違反約束的行;
VALIDATE 表示數(shù)據(jù)庫(kù)驗(yàn)證表中的已存在數(shù)據(jù)是否符合約束;
NOVALIDATE 表示數(shù)據(jù)庫(kù)不驗(yàn)證表中已存在數(shù)據(jù)是否符合約束。
Oracle默認(rèn)約束狀態(tài)為ENABLE、VALIDATE。
下面看Oracle官方給出的匯總:
Modified Data | Existing Data | Summary |
---|---|---|
|
| Existing and future data must obey the constraint. An attempt to apply a new constraint to a populated table results in an error if existing rows violate the constraint. |
|
| The database checks the constraint, but it need not be true for all rows. Thus, existing rows can violate the constraint, but new or modified rows must conform to the rules. |
|
| The database disables the constraint, drops its index, and prevents modification of the constrained columns. |
|
| The constraint is not checked and is not necessarily true. |
下面使用實(shí)例測(cè)試各狀態(tài):
創(chuàng)建測(cè)試表
zx@ORA11G>create table t1 (id number,name varchar2(10),address varchar2(10)); Table created. zx@ORA11G>insert into t1 values(1,'zx','hb'); 1 row created. zx@ORA11G>insert into t1 values(1,'zq','jx'); 1 row created. zx@ORA11G>insert into t1 values(2,'wl','sd'); 1 row created. zx@ORA11G>commit; Commit complete.
1、測(cè)試ENABLE、VALIDATE狀態(tài)
zx@ORA11G>alter table t1 add constraint t1_uk unique(id); alter table t1 add constraint t1_uk unique(id) * ERROR at line 1: ORA-02299: cannot validate (ZX.T1_UK) - duplicate keys found
因?yàn)閕d列中有重復(fù)值,此時(shí)創(chuàng)建約束t1_uk的狀態(tài)為ENABLE、VALIDATE會(huì)驗(yàn)證表中已存在的數(shù)據(jù),所以創(chuàng)建約束不成功。刪除表中的重復(fù)數(shù)據(jù)再次創(chuàng)建約束即可成功。
zx@ORA11G>delete from t1 where id=1 and name='zq'; 1 row deleted. zx@ORA11G>commit; Commit complete. zx@ORA11G>alter table t1 add constraint t1_uk unique(id); Table altered. zx@ORA11G>select table_name,constraint_name,constraint_type,deferrable,status,validated from user_constraints where table_name='T1'; TABLE_NAME CONSTRAINT_NAME C DEFERRABLE STATUS VALIDATED ------------------------------ ------------------------------ - -------------- -------- ------------- T1 T1_UK U NOT DEFERRABLE ENABLED VALIDATED
創(chuàng)建完成后再次插入id=1的數(shù)據(jù)即會(huì)報(bào)錯(cuò),說(shuō)明約束狀態(tài)為ENABLE
zx@ORA11G>insert into t1 values(1,'zq','jx'); insert into t1 values(1,'zq','jx') * ERROR at line 1: ORA-00001: unique constraint (ZX.T1_UK) violated
2、測(cè)試ENABLE、DISABLED狀態(tài)
zx@ORA11G>select * from t1; ID NAME ADDRESS ---------- ---------- ---------- 1 zx hb 2 wl sd 1 zq jx zx@ORA11G>alter table t1 add constraint t1_uk unique(id) enable novalidate; alter table t1 add constraint t1_uk unique(id) enable novalidate * ERROR at line 1: ORA-02299: cannot validate (ZX.T1_UK) - duplicate keys found
直接創(chuàng)建unique約束報(bào)錯(cuò),因?yàn)橛兄貜?fù)值。但先在id列上創(chuàng)建索引,然后創(chuàng)建unique約束即可成功。
zx@ORA11G>create index idx_t_id on t1(id); Index created. zx@ORA11G>alter table t1 add constraint t1_uk unique(id) using index idx_t_id enable novalidate; Table altered. zx@ORA11G>select * from t1; ID NAME ADDRESS ---------- ---------- ---------- 1 zx hb 2 wl sd 1 zq jx zx@ORA11G>select table_name,constraint_name,constraint_type,deferrable,status,validated from user_constraints where table_name='T1'; TABLE_NAME CONSTRAINT_NAME C DEFERRABLE STATUS VALIDATED ------------------------------ ------------------------------ - -------------- -------- ------------- T1 T1_UK U NOT DEFERRABLE ENABLED NOT VALIDATED
原表中的id列中有重復(fù)值,還是可以創(chuàng)建unique約束,因?yàn)闋顟B(tài)指定為NOVALIDATE,不驗(yàn)證表中已有的數(shù)據(jù)。另外因?yàn)闋顟B(tài)為ENABLE,再次插入重復(fù)值報(bào)錯(cuò):
zx@ORA11G>insert into t1 values(2,'yc','bj'); insert into t1 values(2,'yc','bj') * ERROR at line 1: ORA-00001: unique constraint (ZX.T1_UK) violated
3、測(cè)試DISABLE、VALIDATE狀態(tài)
zx@ORA11G>select * from t1; ID NAME ADDRESS ---------- ---------- ---------- 1 zx hb 2 wl sd zx@ORA11G>alter table t1 add constraint t1_uk unique(id) using index idx_t_id disable validate; Table altered. zx@ORA11G>select table_name,constraint_name,constraint_type,deferrable,status,validated from user_constraints where table_name='T1'; TABLE_NAME CONSTRAINT_NAME C DEFERRABLE STATUS VALIDATED ------------------------------ ------------------------------ - -------------- -------- ------------- T1 T1_UK U NOT DEFERRABLE DISABLED VALIDATED zx@ORA11G>insert into t1 values(1,'zq','jx'); insert into t1 values(1,'zq','jx') * ERROR at line 1: ORA-25128: No insert/update/delete on table with constraint (ZX.T1_UK) disabled and validated
DISABLE、VALIDATE狀態(tài)下,不允許做增刪改操作。
4、測(cè)試DISABLE、NOVALIDATE狀態(tài)
zx@ORA11G>select * from t1; ID NAME ADDRESS ---------- ---------- ---------- 1 zx hb 2 wl sd 1 zq jx zx@ORA11G>alter table t1 add constraint t1_uk unique(id) using index idx_t_id disable novalidate; Table altered. zx@ORA11G>select table_name,constraint_name,constraint_type,deferrable,status,validated from user_constraints where table_name='T1'; TABLE_NAME CONSTRAINT_NAME C DEFERRABLE STATUS VALIDATED ------------------------------ ------------------------------ - -------------- -------- ------------- T1 T1_UK U NOT DEFERRABLE DISABLED NOT VALIDATED zx@ORA11G>insert into t1 values(2,'yc','bj'); 1 row created. zx@ORA11G>commit; Commit complete. zx@ORA11G>select * from t1; ID NAME ADDRESS ---------- ---------- ---------- 1 zx hb 2 wl sd 1 zq jx 2 yc bj
約束狀態(tài)為DISABLE、NOVALIDATE,對(duì)新數(shù)據(jù)和老數(shù)據(jù)都不做驗(yàn)證。
二、驗(yàn)證機(jī)制
1. 兩種驗(yàn)證時(shí)機(jī).
Oracle的constraints(約束) 根據(jù)驗(yàn)證時(shí)機(jī)可以分成兩種.
case 1. 在每一句insert statement 執(zhí)行時(shí)就會(huì)馬上驗(yàn)證, 如果約束驗(yàn)證失敗, 則這句sql statement 會(huì)執(zhí)行失敗.
case 2. 執(zhí)行insert statements 時(shí)不會(huì)驗(yàn)證, 在commit的時(shí)候驗(yàn)證, 如果驗(yàn)證失敗, 則整個(gè)Transaction 回滾.
2.constraints的分類(lèi)
對(duì)應(yīng)地, oracle 的 constraints 也可以分成兩大類(lèi).
一種是not deferrable (不可以延時(shí)的) . 這種情況下只能執(zhí)行 case1 的驗(yàn)證時(shí)機(jī)(即時(shí)驗(yàn)證)
另一種是 deferrable (可以設(shè)置成延時(shí)的). 這種情況下可以執(zhí)行 case 1 或 case2 的驗(yàn)證時(shí)機(jī). 但需要設(shè)置.
對(duì)于第二種defferable 分類(lèi), 還可以分成兩小類(lèi).
一種是 initially immediate , 意思時(shí)默認(rèn)情況下執(zhí)行case 1.
另一種是initially deferred, 意思是默認(rèn)情況下執(zhí)行case2.
也就是可以分成三種,如下圖:
2.1、not deferrable
這種最常見(jiàn)也最簡(jiǎn)單. 如果在增加1個(gè)constraint 時(shí)不指定驗(yàn)證時(shí)機(jī)屬性. 默認(rèn)情況下就會(huì)被設(shè)為not deferrable.既然constraint 是不可以延時(shí)驗(yàn)證的, 所以也不用設(shè)定它的初始屬性(實(shí)際上就是initially immediate)。
清空上面的t1表,并創(chuàng)建一個(gè)unique約束
zx@ORA11G>truncate table t1; Table truncated. zx@ORA11G>select * from t1; no rows selected zx@ORA11G>alter table t1 add constraint t1_uk unique (id) not deferrable; Table altered. zx@ORA11G>select table_name,constraint_name,constraint_type,deferrable,status,validated from user_constraints where table_name='T1'; TABLE_NAME CONSTRAINT_NAME C DEFERRABLE STATUS VALIDATED ------------------------------ ------------------------------ - -------------- -------- ------------- T1 T1_UK U NOT DEFERRABLE ENABLED VALIDATED
約束為NOT DEFERRABLE狀態(tài),插入測(cè)試數(shù)據(jù)查看狀態(tài):
zx@ORA11G>insert into t1 values(1,'zx','hb'); 1 row created. zx@ORA11G>insert into t1 values(2,'wl','sd'); 1 row created. zx@ORA11G>insert into t1 values(1,'zq','jx'); insert into t1 values(1,'zq','jx') * ERROR at line 1: ORA-00001: unique constraint (ZX.T1_UK) violated zx@ORA11G>select * from t1; ID NAME ADDRESS ---------- ---------- ---------- 1 zx hb 2 wl sd
插入第三條數(shù)據(jù)時(shí)因?yàn)橛兄貜?fù)數(shù)據(jù),直接報(bào)錯(cuò),說(shuō)明驗(yàn)證時(shí)機(jī)為case1:即時(shí)驗(yàn)證,但不會(huì)回滾之前插入的結(jié)果。
2.2、 deferrable、initially immediate狀態(tài)
zx@ORA11G>alter table t1 drop constraint t1_uk; Table altered. zx@ORA11G>alter table t1 add constraint t1_uk unique (id) deferrable initially immediate; Table altered. zx@ORA11G>select table_name,constraint_name,constraint_type,deferrable,status,validated from user_constraints where table_name='T1'; TABLE_NAME CONSTRAINT_NAME C DEFERRABLE STATUS VALIDATED ------------------------------ ------------------------------ - -------------- -------- ------------- T1 T1_UK U DEFERRABLE ENABLED VALIDATED zx@ORA11G>insert into t1 values(1,'zx','hb'); 1 row created. zx@ORA11G>insert into t1 values(2,'wl','sd'); 1 row created. zx@ORA11G>insert into t1 values(1,'zq','jx'); insert into t1 values(1,'zq','jx') * ERROR at line 1: ORA-00001: unique constraint (ZX.T1_UK) violated zx@ORA11G>select * from t1; ID NAME ADDRESS ---------- ---------- ---------- 1 zx hb 2 wl sd
插入第三條數(shù)據(jù)時(shí)報(bào)錯(cuò)因?yàn)橛兄貜?fù)值,說(shuō)明驗(yàn)證時(shí)機(jī)為case1:即時(shí)驗(yàn)證,這與前一種狀態(tài)一樣。那為什么還要設(shè)置這樣一種狀態(tài)呢?我們來(lái)執(zhí)行下面的語(yǔ)句:
zx@ORA11G>set constraint t1_uk deferred; Constraint set.
上面的語(yǔ)句并沒(méi)有改變這個(gè)constraint的任何屬性, 只不過(guò)是切換為另一種模式
也就是說(shuō)初始是immediate模式的, 執(zhí)行上面的語(yǔ)句后就臨時(shí)變成deferred模式了.
再次執(zhí)行前面的插入語(yǔ)句:
zx@ORA11G>insert into t1 values(1,'zx','hb'); 1 row created. zx@ORA11G>insert into t1 values(2,'wl','sd'); 1 row created. zx@ORA11G>insert into t1 values(1,'zq','jx'); 1 row created.
第三條也能插入進(jìn)去,下面嘗試commit:
zx@ORA11G>commit; commit * ERROR at line 1: ORA-02091: transaction rolled back ORA-00001: unique constraint (ZX.T1_UK) violated zx@ORA11G>select * from t1; no rows selected
commit時(shí)報(bào)錯(cuò),查詢(xún)t1表,沒(méi)有任何數(shù)據(jù),說(shuō)明回滾了整個(gè)事務(wù)。即case2:延遲驗(yàn)證。此時(shí)再次執(zhí)行上面的三次插入操作:
zx@ORA11G>insert into t1 values(1,'zx','hb'); 1 row created. zx@ORA11G>insert into t1 values(2,'wl','sd'); 1 row created. zx@ORA11G>insert into t1 values(1,'zq','jx'); insert into t1 values(1,'zq','jx') * ERROR at line 1: ORA-00001: unique constraint (ZX.T1_UK) violated
從上面結(jié)果可以看出,插入第三行時(shí)又報(bào)錯(cuò),說(shuō)明上面的set constraint語(yǔ)句的作用范圍只有當(dāng)前的一個(gè)事務(wù)。事務(wù)結(jié)束后即約束狀態(tài)即回到原模式。
2.3、deferrable、initially deferred
有了上面的第二個(gè)實(shí)驗(yàn)就可以很容易的理解這一狀態(tài)了。
zx@ORA11G>alter table t1 drop constraint t1_uk; Table altered. zx@ORA11G>alter table t1 add constraint t1_uk unique (id) deferrable initially deferred; Table altered. zx@ORA11G>select table_name,constraint_name,constraint_type,deferrable,status,validated from user_constraints where table_name='T1'; TABLE_NAME CONSTRAINT_NAME C DEFERRABLE STATUS VALIDATED ------------------------------ ------------------------------ - -------------- -------- ------------- T1 T1_UK U DEFERRABLE ENABLED VALIDATED zx@ORA11G>insert into t1 values(1,'zx','hb'); 1 row created. zx@ORA11G>insert into t1 values(2,'wl','sd'); 1 row created. zx@ORA11G>insert into t1 values(1,'zq','jx'); 1 row created. zx@ORA11G>commit; commit * ERROR at line 1: ORA-02091: transaction rolled back ORA-00001: unique constraint (ZX.T1_UK) violated zx@ORA11G>select * from t1; no rows selected
參考:http://blog.csdn.net/nvd11/article/details/12654691
http://docs.oracle.com/cd/E11882_01/server.112/e40540/datainte.htm#CNCPT33337