一、五種約束
如果DML操作所涉及數據違反了已定義的約束,則數據庫系統將拒絕執行這樣的操作。
Oracle數據庫中,約束具體包括非空(NOT NULL)約束、唯一鍵(UNIQUE)約束、主鍵(PRIMARY KEY)約束、外鍵(FOREIGN KEY)約束和檢查(CHECK)約束五種。
和數據表類似,約束也屬於數據庫對象,可以在建表的同時創建其相關約束,也可以在建表后單獨添加;可以由用戶命名,也可以由系統按照默認格式自動對約束進行命名;按照約束的定義位置,又可以分為表級約束和字段級約束兩種。
建表的同時創建約束的的語法格式為:
其中,column_constraint為字段級約束,字段級約束在字段定義時一並給出,也只能約束其所屬的單個字段;table_constraints為表級約束,與表中的字段並列定義,可以約束單個或多個字段。
1、非空約束(只能在字段級定義)
例子:
查詢數據字典視圖user_constraints可得到其具體名稱,SQL語句如下:
2、唯一性約束(列中最多有一個空值)
Oracle會自動為唯一性約束的字段創建相應的唯一性索引。唯一性約束既可以在字段級定義、也可以在表級定義。
如果要在兩個或兩個以上字段上定義聯合唯一鍵(字段組合不允許出現空值),就只能定義為表級約束了,例如:
3、主鍵約束(非空且唯一)
只允許一個主鍵,主鍵可以是單個字段或多字段的組合(聯合主鍵),Oracle會自動為主鍵字段創建對應的唯一性索引。主鍵約束既可以在字段級定義、也可以在表級定義。
區別:主鍵是唯一的。
聯合主鍵只能定義為表級約束:
4、外鍵約束
表級、字段級均可。
外鍵約束的特征:
(1)子表外鍵字段的值必須在主表被參照字段值得范圍內,或者為NULL;
(2)外鍵參照的必須是主表的主鍵或唯一鍵(??);
(3)主表主鍵/唯一鍵被子表參照時,主表相應記錄不允許被刪除。
使用外鍵約束的相關原則:
(1)創建數據表時,先創建主表,后創建子表;刪除表的順序相反;
(2)添加數據時,先向主表中添加/插入記錄,后向子表添加記錄;刪除數據操作順序相反;
(3)修改數據(UPDATE)的情況要復雜一些,通常使用觸發器實現。
外鍵約束可以和主鍵約束同時使用:
外鍵約束也可能構建於同一個表內部的兩個字段之間:
5、檢查約束
表級、字段級均可。
檢查約束的條件表達式中不允許出現如下內容:
- currval, nextval, level, rownum等偽劣
- sysdate, uid, user, userenv等函數
- 對其它字段值的引用
其中, uid, user, userenv函數分別用於獲取當前數據庫用戶ID,用戶名及客戶端計算機信息,如:
二、約束管理
1、查看約束
如要查看當前用戶的所有約束,可查詢用戶字典視圖user_constrains:
其返回結果中的"CONSTRAINT_TYPE"字段以縮寫的方式標明約束條件的具體類型:"P"代表主鍵約束、 代表外鍵約束、"U"代表唯一鍵約束,檢查和非空約束均使用"C"標明。
如果想知道約束建立在哪個字段上,則需要查詢用戶字典視圖user_cons_columns:
2、添加約束(添加非空約束格式特別)
建表后添加非空約束的格式有些特別——必須使用MODIFY子句添加,實際上是修改了整個字段的定義(也可以同時修改字段類型、缺省值等),例如:
3、刪除約束
其中,CASCADE用於指定刪除當前約束的級聯約束。
刪除主鍵約束還有另外一種方式,其語法格式為:
在刪除約束時,如果還存在與該約束相關聯的其他約束(如外鍵/關聯)稱為級聯約束,則刪除操作會失敗,此時可使用CASCADE子句將其他關聯約束一並刪除。如:
在刪除表中字段時,如果該字段處於多字段聯合約束條件(聯合主鍵、聯合唯一鍵、存在參照當前字段的外鍵)中,則刪除會失敗,此時可使用CASCADE CONSTRAINT子句將與該字段相關的約束一並刪除。例如:
4、禁用約束
在ALTER TABLE語句中,還可以使用DISABLE CONSTRAINT子句禁用已有約束,即關閉數據校驗功能,還可以使用CASCADE選項將相關聯的約束一並禁用。其語法格式如下:
相應地,可以使用ENABLE CONSTRAINT子句啟用先前被禁用的約束,例如:
和關閉約束操作的情形有所不同,此時無法再使用CASCADE選項一並啟用相關聯的其它約束。