在數據庫中使用約束(constraints)是為了在該數據庫中實施所謂的“業務規則”其實就是防止非法信息進入數據庫,滿足管理員和應用開發人員所定義的規則集。
ORACLE使用完整性約束(integrity constraints)防止不合法的數據寫入數據庫,管理員和開發人員可以定義完整性規則,增強商業規則,限制數據表中的數據。如果一個DML語句執行的任何結果破壞了完整性約束,ORACLE就會回滾語句,返回錯誤信息。
約束是通過使用CREATE TABLE或ALTER TABLE語句生成的。(建立表時或者表建立后修改都可)如果相關的約束定義在單列上,可以在列這一級指定約束的定義;多列約束必須定義在數據表級,相關的列要在括號中指定,用逗號分隔。如果沒有為約束提供一個名字,那么ORACLE會分配一個系統生成的唯一名字,以SYS_開頭,你可以使用關鍵字CONSTRAINTS后面跟隨相關的約束名字來為約束指定名字。
約束定義存儲在數據字典中,查詢USER_CONSTRAINTS可以獲得相關信息。
select * from user_constraints; //查詢當前用戶的約束
select * from dba_constraints; //查詢所有用戶的約束
ORACLE支持五種類型的完整性約束:
NOT NULL (非空)--防止NULL值進入指定的列,在單列基礎上定義,默認情況下,ORACLE允許在任何列中有NULL值。
CHECK (檢查)--檢查在約束中指定的條件是否得到了滿足。
UNIQUE (唯一)--保證在指定的列中沒有重復值。在該表中每一個值或者每一組值都將是唯一的。
PRIMARY KEY (主鍵)--用來唯一的標識出表的每一行,並且防止出現NULL值,一個表只能有一個主鍵約束。
POREIGN KEY (外部鍵)--通過使用公共列在表之間建立一種父子(parent-child)關系,在表上定義的外部鍵可以指向主鍵或者其他表的唯一鍵。
幾種約束並案例:
1.主鍵約束:
要對一個列加主鍵約束的話,這列就必須要滿足的條件就是分空
因為主鍵約束:就是對一個列進行了約束,約束為(非空、不重復)
以下是代碼 要對一個列加主鍵,列名為id,表名為emp
格式為:
alter table 表格名稱 add constraint 約束名稱 增加的約束類型 (列名)
例子:
alter table emp add constraint ppp primary key (id)
2.check約束:
就是給一列的數據進行了限制
比方說,年齡列的數據都要大於20的
表名(emp) 列名(age)
格式:
alter table 表名稱 add constraint 約束名稱 增加的約束類型 (列名)
例子:
alter table emp add constraint xxx check(age>20)
3.unique約束:
這樣的約束就是給列的數據追加的不重復的約束類型
格式:
alter table 表名 add constraint 約束名稱 約束類型(列名)
比方說可以給ename列加個unique,讓ename列的數據不重復
例子:
alter table emp add constraint qwe unique(ename);
4.默認約束:
意思很簡單就是讓此列的數據默認為一定的數據
格式:
alter table 表名稱 add constraint 約束名稱 約束類型 默認值) for 列名
比方說:emp表中的gongzi列默認為10000
alter table emp add constraint jfsd default 10000 for gongzi
5.外鍵約束:
這個有點難理解了,外鍵其實就是引用
因為主鍵實現了實體的完整性,
外鍵實現了引用的完整性,
應用完整性規定,所引用的數據必須存在!
其實就是個引用,
比方說一個表名稱叫dept 里面有2列數據 一列是ID一列是ENAME
id:表示產品的編號
ename:表示產品的名稱
另外一個表格名稱是emp 里面有2列數據,一列是ID 一列是DID
id:表示用戶號
did:表示購買的產品號
要讓emp表中的did列去引用dept表中的id
可以用下面的方法
格式:
alter table 表名 add constraint 約束名稱 約束類型 (列名) references 被引用的表名稱 (列名)
例子:
alter table emp add constraint jfkdsj foreign key (did) references dept (id)
學習約束練習:
定義約束
CREATE TABLE [schema.]table
(column datatype [DEFAULT expr]
[column_constraint],
...
[table_constraint][,...]);
CREATE TABLE employees
(employee_id NUMBER(6),
first_name VARCHAR2(20),
...
job_id VARCHAR2(10) NOT NULL,
CONSTRAINTS emp_emp_id_pk PRIMARY KEY (EMPLOYEE_ID));
列級的約束定義
column [CONSTRAINT constraint_name] constraint_type,
表級約束的定義
column,..
[CONSTRAINT constraint_name] constraint_type (column,...)
NOT NULL約束
只能定義在列級,不能定義在表級.
CREATE TABLE employees
(employee_id NUMBER(6),
last_name VARCHAR2(25) NOT NULL, //沒有指定名字,將用系統SYS_命名
salary NUMBER(8,2),
commission_pct NUMBER(2,2),
hire_date DATE CONSTRAINT emp_hire_date_nn NOT NULL); //用戶定義了名字
UNIQUE約束
用來保護一個表中的一個或者多個列沒有任何兩行在收到保護的列中具有重復的數據.ORACLE在唯一鍵列上自動生成一個唯一索引以實現唯一性
CREATE TABLE employees
(employee_id NUMBER(6),
last_name VARCHAR2(25) NOT NULL,
salary NUMBER(8,2),
commission_pct NUMBER(2,2),
hire_date DATE NOT NULL,
CONSTRAINT emp_email_uk UNIQUE(email));
PRIMARY KEY約束
唯一鍵的所有特征都適用於主鍵約束,只是在主鍵列中不允許有NULL值.一個表只能有一個主鍵.
CREATE TABLE departments
(department_id NUMBER(4),
department_name VARCHAR2(30) CONSTRAINT dept_name_nn NOT NULL,
manager_id NUMBER(6),
location_id NUMBER(4),
CONSTRAINT dept_id_pk PRIMARY KEY(department_id));
FOREIGN KEY 約束
用來保護一個表中的一個或者多個列,它會通過一個主鍵主鍵或者唯一鍵保證對於每個非NULL值在數據庫的其他地方都有一個數據可用.這個外部鍵就是在生成此約束的表(子表)中的一個或多個列,在父級表和子表中,相關列的數據類型必須匹配.外部鍵列和引用鍵(reference key)列可以位於相同的表中(自引用完整性約束).
CREATE TABLE employees
(employee_id NUMBER(6),
last_name VARCHAR2(25) NOT NULL,
salary NUMBER(8,2),
commission_pct NUMBER(2,2),
hire_date DATE NOT NULL,
deparment_id NUMBER(4),
CONSTRAINT emp_dept_fk FOREIGN KEY(department_id) REFERENCES departments(department_id),
CONSTRAINT emp_email_uk UNIQUE(email));
上例中是在表級定義外部鍵約束,如果在列級定義,不同的是:
CREATE TABLE employees
(...,
department_id NUMBER(4) CONSTRAINT emp_deptid_fk REFERENCES departments(department_id),
...);
//沒有關鍵字FOREIGN KEY
FOREIGN KEY約束還有兩個關鍵字是
ON DELETE CASCADE --當刪除所引用的父表記錄時,刪除子表中相關的記錄
ON DELETE SET NULL--與上面不同的是刪除時,轉換子表中相關記錄為NULL值
默認情況下,如果沒有指定以上兩個中任一,則父表中被引用的記錄將不能被刪除。
CHECK 約束
[CONSTRAINT
這里CHECK子句中的CONDITION應該求值為一個布爾值結果,並且可以引用相同行中其他列的值;不能包含子查詢,序列,環境函數(SYSDATE,UID,USER,USERENV)和偽列(ROWNUM,LEVEL,CURRVAL,NEXTVAL),一個列上可以定義多個CHECK約束,如果所定義的條件為FALSE,則語句將回滾.
CREATE TABLE employees
(...,
salary NUMBER(8,2) CONSTRAINT emp_salary_min CHECK (salary>0),
...);
添加約束
ALTER TABLE employees
ADD CONSTRAINT emp_manager_fk FOREIGN KEY(manager_id) REFERENCES employees(employee_id);
刪除約束
ALTER TABLE employees
DROP CONSTRAINT emp_manager_fk;
ALTER TABLE departments
DROP PRIMARY KEY CASCADE; //由於departments被employees.department_id引用了
對於NOT NULL約束,用ALTER TABLE MODIFY子句來刪除
ALTER TABLE employees MODIFY last_name NULL;
關閉約束
ALTER TABLE employees
DISABLE CONSTRAINT emp_emp_id_pk CASCADE; //如果沒有被引用則不需CASCADE關鍵字
當你生成一個約束時,約束自動打開(除非你指定了DISABLE子句0,當用DISABLE關閉UNIQUE或者PRIMARY KEY約束時,ORACLE會自動刪除相關的唯一索引,再次打開時,ORACLE又會自動建立的.
打開約束
ALTER TABLE employees
ENABLE CONSTRAINT emp_emp_id_pk; //注意,打開一個先前關閉的被引用的主鍵約束,並不能自動打開相關的外部鍵約束
可以從USER_CONSTRAINTS表和USER_CONS_COLUMNS視圖中查詢約束的信息
SELECT constraint_name,constraint_type,search_condition
FROM user_constraints
WHERE table_name='EMPLOYEES';
約束類型
C--CHECK和NOT NULL都算為C TYPE
P--PRIMARY KEY
R--REFERENTIAL INTEGRITY就是外部鍵約束
U--UNIQUE
SELECT constraint_name,column_name
FROM user_cons_columns
WHERE table_name='EMPLOYEES';