Oracle約束的啟用和停用

2022-06-14 09:39:12 字數 3819 閱讀 8445

關於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...