1. 程式人生 > 其它 >Oracle筆記15——Oracle約束

Oracle筆記15——Oracle約束

約束

約束 說明
NOT NULL 非空約束,指定某列的所有行資料不能包含空值
UNIQUE 唯一約束,指定列或者列的組合的所有行資料必須唯一
PRIMARY KEY 主鍵約束,表的每行的唯一性標識,指定列或者列的組合的所有行資料必須唯一
FOREIGN KEY 外來鍵約束,在列及引用列上建立的一種強制依賴關係
CHECK 檢查性約束,在列上指定一個必須滿足的條件

一、

NOT NULL(非空約束):不能為NULL 或者 ''
1.約束的列值不能為NULL
2.只能定義列級別的約束
3.可以不用指定約束名稱

1.建立表emp_bak,指定ename不能為NULL
CREATE 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;--檢視約束關聯的列資訊