| 約束類型 | 核心功能 | 是否允許 NULL | 每表數量限制 |
|---|---|---|---|
| NOT NULL | 欄位不可為空 | 不允許 | 無限制 |
| UNIQUE | 鍵值唯一 | 允許單一 NULL(Oracle/SQL Server) | 多個 |
| PRIMARY KEY | 主鍵 = UNIQUE + NOT NULL | 不允許 | 僅一個 |
| FOREIGN KEY | 參考完整性 | 允許(視定義) | 多個 |
| CHECK | 自定義條件驗證 | 視條件而定 | 多個 |
-- SQL Server
CREATE TABLE U_emp(
empno BIGINT,
ename VARCHAR(10) NOT NULL,
job VARCHAR(9),
mgr BIGINT,
hiredate DATE,
sal DECIMAL(7,2),
comm DECIMAL(7,2),
deptno DECIMAL(7,2) NOT NULL
);
-- Oracle
CREATE TABLE emp(
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(7,2) NOT NULL
);
-- DB2
CREATE TABLE U_emp(
empno INTEGER,
ename VARCHAR(10) NOT NULL,
job VARCHAR(9),
mgr INTEGER,
hiredate DATE,
sal DECIMAL(7,2),
comm DECIMAL(7,2),
deptno DECIMAL(7,2) NOT NULL
);
關鍵差異:資料型別命名(
BIGINTvsNUMBERvsINTEGER,VARCHARvsVARCHAR2),約束語法完全相同。
-- SQL Server / Oracle:dname 可為 NULL(但僅一筆)
CREATE TABLE dept(
deptno NUMBER(2),
dname VARCHAR2(14),
loc VARCHAR2(13),
CONSTRAINT dept_dname_uk UNIQUE(dname)
);
-- DB2:UNIQUE 欄位通常建議加 NOT NULL 避免歧義
CREATE TABLE U_dept(
deptno INTEGER,
dname VARCHAR(14) NOT NULL, -- DB2 最佳實踐
loc VARCHAR(13),
CONSTRAINT dept_dname_uk UNIQUE(dname)
);
-- 三平台通用模式:表級約束定義
CREATE TABLE dept(
deptno NUMBER(2) / INTEGER,
dname VARCHAR2(14) / VARCHAR(14),
loc VARCHAR2(13) / VARCHAR(13),
CONSTRAINT dept_dname_uk UNIQUE(dname),
CONSTRAINT dept_deptno_pk PRIMARY KEY(deptno)
);
-- DB2 差異:PK 欄位通常顯式加 NOT NULL
-- deptno INTEGER NOT NULL,
-- SQL Server / DB2:參考表名通常加 schema/owner 前綴
CREATE TABLE F_emp(
empno INTEGER,
ename VARCHAR(10) NOT NULL,
job VARCHAR(9),
mgr INTEGER,
hiredate DATE,
sal DECIMAL(7,2),
comm DECIMAL(7,2),
deptno INTEGER NOT NULL,
CONSTRAINT emp_deptno_fk FOREIGN KEY(deptno)
REFERENCES p_dept(deptno)
);
-- Oracle:參考表名無需 schema(同用戶下)
CREATE TABLE emp(
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(7,2) NOT NULL,
CONSTRAINT emp_deptno_fk FOREIGN KEY(deptno)
REFERENCES dept(deptno)
);
-- 級聯刪除:刪除父記錄時自動刪除子記錄
CONSTRAINT emp_deptno_fk FOREIGN KEY(deptno)
REFERENCES dept(deptno) ON DELETE CASCADE
-- 級聯設 NULL:刪除父記錄時子記錄 FK 設為 NULL(FK 欄位必須允許 NULL)
CONSTRAINT emp_deptno_fk FOREIGN KEY(deptno)
REFERENCES dept(deptno) ON DELETE SET NULL
-- 無動作/限制(預設):存在子記錄時禁止刪除父記錄
CONSTRAINT emp_deptno_fk FOREIGN KEY(deptno)
REFERENCES dept(deptno) ON DELETE NO ACTION -- SQL Server/DB2
-- Oracle 用 ON DELETE RESTRICT
-- 三平台通用
CREATE TABLE test(
deptno NUMBER(2) / BIGINT,
CONSTRAINT emp_deptno_ck CHECK(deptno BETWEEN 10 AND 99)
);
-- 進階:多欄位條件
CONSTRAINT chk_sal_comm CHECK(sal > comm OR comm IS NULL)
-- 複雜條件可用 CASE/函數
CONSTRAINT chk_hiredate CHECK(hiredate <= SYSDATE) -- Oracle
CONSTRAINT chk_hiredate CHECK(hiredate <= GETDATE()) -- SQL Server
CONSTRAINT chk_hiredate CHECK(hiredate <= CURRENT DATE) -- DB2
| 類型 | 命名模式 | 範例 |
|---|---|---|
| Primary Key | PK_<表名> | PK_EMP |
| Foreign Key | FK_<子表>_<父表> | FK_EMP_DEPT |
| Unique | UK_<表名>_<欄位> | UK_EMP_EMAIL |
| Check | CK_<表名>_<描述> | CK_EMP_SAL_POSITIVE |
| Not Null | 通常不命名(欄位級) | — |
-- 推薦:表級定義,易讀、易維護、支援複合鍵
CREATE TABLE emp(
empno NUMBER(4),
ename VARCHAR2(10) NOT NULL,
deptno NUMBER(2),
CONSTRAINT PK_EMP PRIMARY KEY(empno),
CONSTRAINT FK_EMP_DEPT FOREIGN KEY(deptno) REFERENCES dept(deptno),
CONSTRAINT UK_EMP_EMAIL UNIQUE(email),
CONSTRAINT CK_EMP_SAL CHECK(sal > 0)
);
-- 不推薦:欄位級分散定義,複合鍵無法表達
CREATE TABLE emp(
empno NUMBER(4) PRIMARY KEY, -- 單欄可接受
ename VARCHAR2(10) NOT NULL,
deptno NUMBER(2) REFERENCES dept(deptno) -- 簡單 FK 可接受
);
-- Oracle / SQL Server
ALTER TABLE emp DISABLE CONSTRAINT FK_EMP_DEPT;
-- 大量載入...
ALTER TABLE emp ENABLE CONSTRAINT FK_EMP_DEPT; -- 會驗證現有資料
-- Oracle 快速啟用不驗證歷史資料(風險自負)
ALTER TABLE emp ENABLE NOVALIDATE CONSTRAINT FK_EMP_DEPT;
-- DB2
ALTER TABLE emp ALTER FOREIGN KEY FK_EMP_DEPT NOT ENFORCED;
-- 載入...
ALTER TABLE emp ALTER FOREIGN KEY FK_EMP_DEPT ENFORCED;
五大核心約束(NOT NULL、UNIQUE、PK、FK、CHECK)在 SQL Server、Oracle、DB2 中語法高度一致,核心差異在於資料型別關鍵字與參考表名稱解析規則。建立統一的「約束設計規範」涵蓋命名、層級、FK 行為、CHECK 條件寫法,是跨平台專案維護資料完整性、降低遷移風險的關鍵基礎設施。