關於oracle的約束概念和基本操作,我已經在以前的《constraint基礎概念》、《constraint的簡單操作》兩篇文章中有過比較詳細的介紹了,但是對於如何停用和啟用constraint沒有作特別的描述,以至於在使用plsql中無法忽略constraint而逐步進行資料的更改,所以在這裡專門記錄一下關於constraint的停用和啟用相關知識。
一、約束的狀態
可以指定啟用(enable)或者停用(disable)約束。如果啟用約束,當在資料庫中輸入或者更新資料時要進行資料檢查,不符合約束規則的資料不能輸入資料庫。如果停用約束,那麼不符合規則的資料也能輸入到資料庫中。 另外,也能制定表中的現有資料必須符合約束(validate);相反地,如果指定為(novalidate),就不能確保現有的資料符合約束。
所以由上述的特性可知,表上的約束可能處在以下4種狀態:
● enable , validate
● enable , novalidate
● disable, validate
● disable, novalidate
1、停用約束的情況
一般來說,約束都是需要始終處於啟用狀態的,但是在以下情況中可能需要約束停用:
● 當往表中裝載大量資料時
● 當執行批操作使得表有大規模的改變時
● 到一次性匯入或匯出乙個表時
停用都是為了提高效能,特別是在資料倉儲中,這種操作的作用尤其明顯。而且由於停用約束有可能造成違反約束的資料輸入到表中,所以在進行完以上的動作之後,需要立即啟用約束。
2、啟用約束的一些問題
在停用約束時,違反約束的行可以插入到表中,這種行為被認為是對約束異常。而且如果約束處於啟用非校驗狀態(enable,novalidate),則在停用時插入的違反約束的記錄仍然保留,需要更改後,約束方可出在已校驗狀態。
當表的約束處於啟用非校驗狀態時,表中原本的資料可以不符合約束,但後面新增的資料必須進行校驗,這對於資料倉儲來說特別有用。因為基本上資料倉儲都是使用增量更新,在停用約束後如果採用啟用校驗約束狀態,則需要對大量資料進行校驗,影響效能。
另外說明:校驗乙個已經啟用的約束,在校驗期間不需要任何dml鎖,因此在校驗期間可以保證沒有引入違反約束的資料。
3、完整性約束狀態:過程和效益
一般可以按照以下的順序來使用約束,以確保最佳的效益:
① 停用狀態
② 執行操作(裝載、匯出、匯入)
③ 啟用非校驗狀態
④ 啟用狀態
好處是:
● 不留鎖
● 所有的約束能夠同時處於啟用狀態
● 約束啟用是並行實現的
● 允許表上進行同步操作
二、在定義中設定約束屬性
在create table和alter table語句中就可以設定約束的enable/disable、validate/novalidate。
注:預設的是enable/validate的。
1、在定義中停用約束
create table emp( empno number(5) primary key disable,
deptno number(2));
alter table emp add primary key(empno) disable;
2、在定義中啟用約束
create table emp( empno number(5) primary key,
deptno number(2));
alter table emp add primary key(empno);
注:有可能建立約束失敗,因為原始資料與約束衝突,此時語句回滾。
3、修改或刪除現有的約束
注:在使用外來鍵參考了primary或unique鍵時,不能停用或刪除被參考約束
停用:alter table dept disable constraint dname_ukey;
alter table dept disable primary key keep index,
disable unique (dname, loc) keep index;
啟用非校驗:
alter table dept enable constraint dname_ukey;
alter table dept enable novalidate primary key,
enable novalidate unique (dname, loc);
啟用校驗:
alter table dept modify constraint dname_ukey validate;
alter table dept modify primary key enable novalidate;
alter table dept disable primary key cascade;
刪除:alter table dept drop unique (dname, loc);
alter table emp drop primary key keep index,
drop constraint dept_fkey;
三、延時約束檢查
oracle可以再事務中先不檢查約束,直到事務結束時才統一檢查。這樣就可以讓事務在處理的過程中暫時得違反約束,例如某時候在往表裡新增資料時,某欄位暫時留空,在下一步中再update資料,以逐步插入資料,這樣就必須用到這個效能。使用set constraints語句進行設定。
在使用這個特性時,需要注意幾點:
● 不能在觸發器內發布set constraints語句
● 可延時的唯一鍵和主鍵必須使用非唯一索引
1、所有約束設定成延時
set constraints all deferred;
注:在所有處理前執行該語句,至事務結束時為止,只適用於當前會話。
2、檢查提交(可選)
在事務commit之前,可以用set constraints all immediate 語句來手工檢查約束的違反情況。雖然在事務結束時會自動隱性執行這條語句,但是也是有一定的存在意義的,例如希望在錯誤時定義某些操作。
四、報告約束異常
如果校驗約束時存在異常,則返回乙個錯誤,且完整性約束仍保持未被校驗狀態。當約束存在異常時,乙個語句就不能正確執行,則此語句被回滾。如果存在異常,必須要更新或刪除了約束的所有異常後,才可以校驗約束。但是在使用alter table語句不能確定哪一行違反約束,為了確定哪一行,在發布enable子句中帶有exception選項的alter table語句。
exception選項將rowid、owner、table、rowid、constraint放到乙個指定的表中。在啟用約束前,硬建立乙個合適的異常報告表,用來接收enable子句的exception選項資訊,可以直接執行'd:\oracle\ora92\rdbms\admin\utlexcpt.sql'或'd:\oracle\ora92\rdbms\admin\utlexcpt1.sql'指令碼來進行建立。注意:這兩個指令碼的區別在於資料庫的相容性級別和所分析的表的型別。
使用的語法如下:
alter table dept enable primary key exceptions into exceptions;
如果存在異常,則直接查詢 select * from exceptions; 即可。如果需要更加詳細的資訊,則可以使用rowid與原表的rowid進行關聯,這樣就可以查出原始表中當前行的所有資訊,並進行修改。
Oracle約束的啟用和停用
關於oracle的約束概念和基本操作,我已經在以前的 constraint基礎概念 constraint的簡單操作 兩篇文章中有過比較詳細的介紹了,但是對於如何停用和啟用constraint沒有作特別的描述,以至於在使用plsql中無法忽略constraint而逐步進行資料的更改,所以在這裡專門記錄...
Oracle約束的啟用和停用
關於oracle的約束概念和基本操作,我已經在以前的 constraint基礎概念 constraint的簡單操作 兩篇文章中有過比較詳細的介紹了,但是對於如何停用和啟用constraint沒有作特別的描述,以至於在使用plsql中無法忽略constraint而逐步進行資料的更改,所以在這裡專門記錄...
SQL中約束和觸發器的停用與啟用
如何對sql中的約束和觸發器進行停用與啟用,如果有外來鍵約束則相關聯表都要進行相應操作。alter table tablename check constrait all 檢查約束 alter table tablename nocheck constrait all 不檢查約束 alter tab...