Oracle筆記15——Oracle約束
約束
約束 | 說明 |
NOT NULL | 非空約束,指定某列的所有行資料不能包含空值 |
UNIQUE | 唯一約束,指定列或者列的組合的所有行資料必須唯一 |
PRIMARY KEY | 主鍵約束,表的每行的唯一性標識,指定列或者列的組合的所有行資料必須唯一 |
FOREIGN KEY | 外來鍵約束,在列及引用列上建立的一種強制依賴關係 |
CHECK | 檢查性約束,在列上指定一個必須滿足的條件 |
一、
NOT NULL(非空約束):不能為NULL 或者 ''
1.約束的列值不能為NULL
2.只能定義列級別的約束
3.可以不用指定約束名稱
1.建立表emp_bak,指定ename不能為NULLCREATE TABLE emp_bak( empno NUMBER(4), ename VARCHAR2(10) NOT NULL,--新增非空約束 job VARCHAR2(9), mgr NUMBER(4), hiredate DATE, sal NUMBER(7, 2), comm NUMBER(7, 2), deptno NUMBER(2) ); --測試 INSERT INTO emp_bak(empno, ename) VALUES(1001, '');--新增資料失敗,ename不能為空INSERT INTO emp_bak(empno, ename) VALUES(1002, 'Lynn');--新增資料成功 SELECT * FROM emp_bak; --刪除表 DROP TABLE emp_bak;
二、
UNIQUE(唯一約束、唯一鍵):
1.約束的列值必須唯一,但是可以為NULL
2.既能定義列級別約束(單列QNIQUE約束),也可以定義表級別的約束(多列組合UNIQUE約束)
3.建議指定約束名稱
4.建立唯一約束時,預設給所有約束的列新增索引INDEX,用於優化查詢效率
5.一個表可以同時定義多個UNIQUE唯一約束
6.可以給一列或多列定義UNIQUE唯一約束
1.建立表emp_bak,指定empno必須唯一、同時ename必須唯一,不指定約束名稱CREATE TABLE emp_bak( empno NUMBER(4) UNIQUE,--不指定約束名稱 ename VARCHAR2(10) UNIQUE,--不指定約束名稱 job VARCHAR2(9), mgr NUMBER(4), hiredate DATE, sal NUMBER(7, 2), comm NUMBER(7, 2), deptno NUMBER(2) ); --測試 INSERT INTO emp_bak(empno, ename) VALUES(1001, 'Lynn'); INSERT INTO emp_bak(empno, ename) VALUES(1001, 'Tom');--新增失敗,違反唯一約束條件(SCOTT.SYS_C0010811) INSERT INTO emp_bak(empno, ename) VALUES(1002, 'Lynn');--新增失敗,違反唯一約束條件(SCOTT.SYS_C0010812) --刪除表 DROP TABLE emp_bak; 2.建立表emp_bak,指定empno必須唯一、同時ename必須唯一,指定約束名稱 CREATE TABLE emp_bak( empno NUMBER(4) CONSTRAINT emp_bak_empno_unique UNIQUE,--指定約束名稱(列級別約束) ename VARCHAR2(10) CONSTRAINT emp_bak_ename_unique UNIQUE,--指定約束名稱(列級別約束) job VARCHAR2(9), mgr NUMBER(4), hiredate DATE, sal NUMBER(7, 2), comm NUMBER(7, 2), deptno NUMBER(2) ); --相當於: CREATE TABLE emp_bak( empno NUMBER(4), ename VARCHAR2(10), job VARCHAR2(9), mgr NUMBER(4), hiredate DATE, sal NUMBER(7, 2), comm NUMBER(7, 2), deptno NUMBER(2), CONSTRAINT emp_bak_empno_unique UNIQUE(empno),--指定約束名稱(表級別約束) CONSTRAINT emp_bak_ename_unique UNIQUE(ename)--指定約束名稱(表級別約束) ); --測試 INSERT INTO emp_bak(empno, ename) VALUES(1001, 'Lynn'); INSERT INTO emp_bak(empno, ename) VALUES(1001, 'Tom');--新增失敗,違反唯一約束條件(SOCTT.EMP_BAK_EMPNO_UNIUQE) INSERT INTO emp_bak(empno, ename) VALUES(1002, 'Lynn');--新增失敗,違反唯一約束條件(SOCTT.EMP_BAK_ENAME_UNIUQE) --刪除表 DROP TABLE emp_bak; SELECT * FROM emp_bak; --同時給多列定義組合唯一約束 1.建立表emp_bak,指定empno、ename組合唯一 CREATE TABLE emp_bak( empno NUMBER(4), ename VARCHAR2(10), job VARCHAR2(9), mgr NUMBER(4), hiredate DATE, sal NUMBER(7, 2), comm NUMBER(7, 2), deptno NUMBER(2), CONSTRAINT emp_bak_empnoandename_unique UNIQUE(empno, ename)--組合約束,只能定義表級別約束 ); --測試 INSERT INTO emp_bak(empno, ename) VALUES(1000, 'Lynn'); INSERT INTO emp_bak(empno, ename) VALUES(1001, 'Lynn');--插入資料成功 INSERT INTO emp_bak(empno, ename) VALUES(1000, 'Tom');--插入資料成功 INSERT INTO emp_bak(empno, ename) VALUES(1000, 'Lynn');--違反唯一約束條件(SOCTT.EMP_BAK_EMPNOANDENAME_UNIUQE) --刪除表 DROP TABLE emp_bak;
三、
PRIMARY KEY(主鍵約束):相當於UNIQUE + NOT NULL
1.約束的列值必須唯一,且不可以為NULL
2.既能定義列級別約束(單列PK約束),也可以定義表級別的約束(多列組合PK約束)
3.建議指定約束名稱
4.建立唯一約束時,預設給所有約束的列新增索引index,用於優化查詢效率
5.一個表只能有一個primary key主鍵約束
6.可以給一列或多列定義primary key主鍵約束
1.建立表emp_bak,指定empno為主鍵 CREATE TABLE emp_bak( empno NUMBER(4) CONSTRAINT emp_bak_empno_pk PRIMARY KEY,--empno設為主鍵(列級別約束) ename VARCHAR2(10), job VARCHAR2(9), mgr NUMBER(4), hiredate DATE, sal NUMBER(7, 2), comm NUMBER(7, 2), deptno NUMBER(2) ); --相當於: CREATE TABLE emp_bak( empno NUMBER(4), ename VARCHAR2(10), job VARCHAR2(9), mgr NUMBER(4), hiredate DATE, sal NUMBER(7, 2), comm NUMBER(7, 2), deptno NUMBER(2), CONSTRAINT emp_bak_empno_pk PRIMARY KEY(empno)--empno設為主鍵(表級別約束) ); --測試 INSERT INTO emp_bak(empno, ename) VALUES(1000, 'Lynn'); INSERT INTO emp_bak(empno, ename) VALUES('', 'Lynn');--插入資料失敗,主鍵不能為空 INSERT INTO emp_bak(empno, ename) VALUES(1000, 'Tom');--插入資料失敗,主鍵要唯一 --刪除表 DROP TABLE emp_bak; --同時給多列定義組合主鍵約束 1.建立表emp_bak,指定empno、ename組合為主鍵 CREATE TABLE emp_bak( empno NUMBER(4), ename VARCHAR2(10), job VARCHAR2(9), mgr NUMBER(4), hiredate DATE, sal NUMBER(7, 2), comm NUMBER(7, 2), deptno NUMBER(2), CONSTRAINT emp_bak_empno_pk PRIMARY KEY(empno, ename)--組合約束,只能定義表級別約束 ); --測試 INSERT INTO emp_bak(empno, ename) VALUES(1000, 'Lynn'); INSERT INTO emp_bak(empno, ename) VALUES(1001, 'Lynn');--插入資料成功 INSERT INTO emp_bak(empno, ename) VALUES(1000, 'Tom');--插入資料成功 INSERT INTO emp_bak(empno, ename) VALUES(1000, 'Lynn');--插入資料失敗,主鍵要唯一 --刪除表 DROP TABLE emp_bak;
四、
FOREIGN KEY(外來鍵約束):
1.外來鍵列的值必須在引用列值的範圍內,或者為NULL
2.外來鍵參照的是列必須是主鍵或者唯一鍵
3.主鍵表主鍵值被外來鍵表參照時,主鍵表記錄不允許被刪除
4.建議指定約束名稱
5.既能定義列級別約束,也可以定義表級別的約束
6.一個表可以有多個外來鍵約束
級聯刪除 ON DELETE CASCADE
級聯清空 ON DELETE SET NULL
1.建立表emp_bak,指定deptno為外來鍵,參考dept表的deptno主鍵列 CREATE TABLE emp_bak( empno NUMBER(4), ename VARCHAR2(10), job VARCHAR2(9), mgr NUMBER(4), hiredate DATE, sal NUMBER(7, 2), comm NUMBER(7, 2), deptno NUMBER(2) CONSTRAINT emp_bak_deptno_fk REFERENCES dept(deptno) ); --相當於 CREATE TABLE emp_bak( empno NUMBER(4), ename VARCHAR2(10), job VARCHAR2(9), mgr NUMBER(4), hiredate DATE, sal NUMBER(7, 2), comm NUMBER(7, 2), deptno NUMBER(2), CONSTRAINT emp_bak_deptno_fk FOREIGN KEY(deptno) REFERENCES dept(deptno) ); --測試 INSERT INTO emp_bak(deptno, ename) VALUES(10, 'Lynn'); INSERT INTO emp_bak(deptno, ename) VALUES(NULL, 'Lynn');--插入資料成功 INSERT INTO emp_bak(deptno, ename) VALUES(50, 'Lynn');--違反完整約束條件(SOCTT.EMP_BAK_DEPTNO_FK)未找到父項關鍵字,因為dept表中dept沒有50 DELETE FROM dept WHERE deptno = 10;--刪除資料失敗,違反完整約束條件(SCOTT,FK_DEPTNO)-已找到子記錄 --刪除表 DROP TABLE emp_bak; --級聯刪除 1.建立表emp_bak,指定deptno為外來鍵,參考dept表的deptno主鍵列;當dept表刪除一個deptno時,emp_bak表對應的記錄也一併刪除 CREATE TABLE emp_bak( empno NUMBER(4), ename VARCHAR2(10), job VARCHAR2(9), mgr NUMBER(4), hiredate DATE, sal NUMBER(7, 2), comm NUMBER(7, 2), deptno NUMBER(2) CONSTRAINT emp_bak_deptno_fk REFERENCES dept(deptno) ON DELETE CASCADE--列級別約束的級聯刪除 ); --相當於 CREATE TABLE emp_bak( empno NUMBER(4), ename VARCHAR2(10), job VARCHAR2(9), mgr NUMBER(4), hiredate DATE, sal NUMBER(7, 2), comm NUMBER(7, 2), deptno NUMBER(2), CONSTRAINT emp_bak_deptno_fk FOREIGN KEY(deptno) REFERENCES dept(deptno) ON DELETE CASCADE--標記別約束的級聯刪除 ); --測試 SELECT * FROM dept; SELECT * FROM emp_bak; INSERT INTO dept VALUES(88, 'STUDENT', 'ZHANJIANG'); INSERT INTO emp_bak(deptno, ename) VALUES(88, 'Lynn'); INSERT INTO emp_bak(deptno, ename) VALUES(88, 'Tom'); INSERT INTO emp_bak(deptno, ename) VALUES(40, 'Amy'); DELETE FROM dept WHERE deptno = 88;--此時emp_bak只剩deptno為40的一條資料 --刪除表 DROP TABLE emp_bak; --級聯清空 1.建立表emp_bak,指定deptno為外來鍵,參考dept表的deptno主鍵列;當dept表刪除一個deptno時,emp_bak表對應記錄的deptno設為空 CREATE TABLE emp_bak( empno NUMBER(4), ename VARCHAR2(10), job VARCHAR2(9), mgr NUMBER(4), hiredate DATE, sal NUMBER(7, 2), comm NUMBER(7, 2), deptno NUMBER(2) CONSTRAINT emp_bak_deptno_fk REFERENCES dept(deptno) ON DELETE SET NULL--列級別約束的級聯清空 ); --相當於 CREATE TABLE emp_bak( empno NUMBER(4), ename VARCHAR2(10), job VARCHAR2(9), mgr NUMBER(4), hiredate DATE, sal NUMBER(7, 2), comm NUMBER(7, 2), deptno NUMBER(2), CONSTRAINT emp_bak_deptno_fk FOREIGN KEY(deptno) REFERENCES dept(deptno) ON DELETE SET NULL--標記別約束的級聯清空 ); --測試 SELECT * FROM dept; SELECT * FROM emp_bak; INSERT INTO dept VALUES(88, 'STUDENT', 'ZHANJIANG'); INSERT INTO emp_bak(deptno, ename) VALUES(88, 'Lynn'); INSERT INTO emp_bak(deptno, ename) VALUES(88, 'Tom'); INSERT INTO emp_bak(deptno, ename) VALUES(40, 'Amy'); DELETE FROM dept WHERE deptno = 88;--此時emp_bak中,原本deptno為88的資料,改為deptno為空 --刪除表 DROP TABLE emp_bak;
五、
CHECK(檢查性約束):
1.約束的列取值範圍,但是可以為NULL
2.建議指定約束名稱
3.既能定義列級別約束,也可以定義表級別的約束
4.一個表可以有多個CHECK鍵約束
1.建立表emp_bak,約束sal必須大於等於3000 CREATE TABLE emp_bak( empno NUMBER(4), ename VARCHAR2(10), job VARCHAR2(9), mgr NUMBER(4), hiredate DATE, sal NUMBER(7, 2) CONSTRAINT emp_bak_sal_check CHECK(sal >= 3000), comm NUMBER(7, 2), deptno NUMBER(2) ); --相當於 CREATE TABLE emp_bak( empno NUMBER(4), ename VARCHAR2(10), job VARCHAR2(9), mgr NUMBER(4), hiredate DATE, sal NUMBER(7, 2), comm NUMBER(7, 2), deptno NUMBER(2), CONSTRAINT emp_bak_sal_check CHECK(sal >= 3000) ); --測試 INSERT INTO emp_bak(empno, sal) VALUES(1001, NULL);--插入資料成功 INSERT INTO emp_bak(empno, sal) VALUES(1001, 2900);--插入資料失敗,違反檢查約束條件(SCOTT.EMP_BAK_SAL_CHECK) INSERT INTO emp_bak(empno, sal) VALUES(1001, 3000);--插入資料成功 --刪除表 DROP TABLE emp_bak; --綜合定義五類約束 --列級別約束 CREATE TABLE emp_bak( empno NUMBER(4) CONSTRAINT emp_bak_empno_pk PRIMARY KEY,--主鍵約束 ename VARCHAR2(10) CONSTRAINT emp_bak_ename_unique UNIQUE,--唯一約束 job VARCHAR2(9) CONSTRAINT emp_bak_job_nn NOT NULL,--非空約束 mgr NUMBER(4), hiredate DATE, sal NUMBER(7, 2) CONSTRAINT emp_bak_sal_check CHECK(sal >= 3000),--檢查性約束 comm NUMBER(7, 2), deptno NUMBER(2) CONSTRAINT emp_bak_deptno_fk REFERENCES dept(deptno)--外來鍵約束 ); --表級別約束 CREATE TABLE emp_bak( empno NUMBER(4), ename VARCHAR2(10), job VARCHAR2(9) CONSTRAINT emp_bak_job_nn NOT NULL,--非空約束 mgr NUMBER(4), hiredate DATE, sal NUMBER(7, 2), comm NUMBER(7, 2), deptno NUMBER(2), CONSTRAINT emp_bak_empno_pk PRIMARY KEY(empno),--主鍵約束 CONSTRAINT emp_bak_ename_unique UNIQUE(ename),--唯一約束 CONSTRAINT emp_bak_sal_check CHECK(sal >= 3000),--檢查性約束 CONSTRAINT emp_bak_deptno_fk FOREIGN KEY(deptno) REFERENCES dept(deptno)--外來鍵約束 ); --刪除表 DROP TABLE emp_bak;
六、
追加約束
語法:
ALTER TABLE 表名 ADD [CONSTRAINT 約束名] 約束型別 (列名);
刪除約束
語法:
ALTER TABLE 表名 DROP PRIMARY KEY | UNIQUE(列名) | CONSTRAINT 約束名 [CASCADE];
禁用約束
語法:
ALTER TABLE 表名 DISABLE CONSTRAINT 約束名 [CASCADE];
啟用約束
語法:
ALTER TABLE 表名 ENABLE CONSTRAINT 約束名;
1.為emp_bak追加約束後,再禁用和啟動約束,最後刪除這些約束(empno為主鍵約束,job為非空約束,ename為唯一約束,sal為檢查性約束並且sal要大於等於3000),deptno為唯一約束關聯表dept中的deptno CREATE TABLE emp_bak( empno NUMBER(4), ename VARCHAR2(10), job VARCHAR2(9), mgr NUMBER(4), hiredate DATE, sal NUMBER(7, 2), comm NUMBER(7, 2), deptno NUMBER(2) ); --追加約束 ALTER TABLE emp_bak ADD CONSTRAINT emp_bak_empno_pk PRIMARY KEY(empno);--主鍵約束 ALTER TABLE emp_bak ADD CONSTRAINT emp_bak_ename_unique UNIQUE(ename);--唯一約束 ALTER TABLE emp_bak ADD CONSTRAINT emp_bak_sal_check CHECK(sal >= 3000);--檢查性約束 ALTER TABLE emp_bak ADD CONSTRAINT emp_bak_deptno_fk FOREIGN KEY(deptno) REFERENCES dept(deptno);--外來鍵約束 ALTER TABLE emp_bak ADD CONSTRAINT emp_bak_job_notnull NOT NULL(job);--追加失敗 ALTER TABLE emp_bak MODIFY job NOT NULL;--非空約束 ALTER TABLE emp_bak MODIFY (job CONSTRAINT emp_bak_job_not_null NOT NULL);--同上,追加非空約束 --禁用約束 ALTER TABLE emp_bak DISABLE CONSTRAINT emp_bak_empno_pk;--主鍵約束 ALTER TABLE emp_bak DISABLE CONSTRAINT emp_bak_ename_unique;--唯一約束 ALTER TABLE emp_bak DISABLE CONSTRAINT emp_bak_sal_check;--檢查性約束 ALTER TABLE emp_bak DISABLE CONSTRAINT emp_bak_deptno_fk;--外來鍵約束 ALTER TABLE emp_bak DISABLE CONSTRAINT emp_bak_job_not_null;--非空約束 --啟用約束 ALTER TABLE emp_bak ENABLE CONSTRAINT emp_bak_empno_pk;--主鍵約束 ALTER TABLE emp_bak ENABLE CONSTRAINT emp_bak_ename_unique;--唯一約束 ALTER TABLE emp_bak ENABLE CONSTRAINT emp_bak_sal_check;--檢查性約束 ALTER TABLE emp_bak ENABLE CONSTRAINT emp_bak_deptno_fk;--外來鍵約束 ALTER TABLE emp_bak ENABLE CONSTRAINT emp_bak_job_not_null;--非空約束 --刪除約束 ALTER TABLE emp_bak DROP CONSTRAINT emp_bak_empno_pk;--主鍵約束 ALTER TABLE emp_bak DROP CONSTRAINT emp_bak_ename_unique;--唯一約束 ALTER TABLE emp_bak DROP CONSTRAINT emp_bak_sal_check;--檢查性約束 ALTER TABLE emp_bak DROP CONSTRAINT emp_bak_deptno_fk;--外來鍵約束 ALTER TABLE emp_bak MODIFY (job NULL);--非空約束
七、
資料字典: P(PRIMARY KEY) R(FOREIGN KEY) C(CHECK, NOT NULL屬於C) U(UNIQUE)
SELECT * FROM USER_CONSTRAINTS;--檢視當前使用者下所有的約束 SELECT * FROM USER_CONS_COLUMNS;--檢視約束關聯的列資訊