UNIQUE 約束確保欄位或欄位組合值不重複,是資料完整性核心機制。本文詳細說明建表時與事後新增兩種建立方式、單欄與複合約束差異、NULL 值處理邏輯、錯誤代碼解讀與管理最佳實務。
CREATE TABLE unique_test (
id NUMBER,
fname VARCHAR2(20),
lname VARCHAR2(20),
address VARCHAR2(100),
email VARCHAR2(40),
CONSTRAINT name_unique UNIQUE (fname, lname) -- 複合唯一約束
);
ALTER TABLE unique_test
ADD CONSTRAINT email_unique UNIQUE (email);
-- 插入第一筆:劉德華
INSERT INTO unique_test (id, fname, lname) VALUES (1, '德華', '劉'); -- 成功
-- 插入重複複合值:再次劉德華
INSERT INTO unique_test (id, fname, lname) VALUES (2, '德華', '劉');
-- ORA-00001: unique constraint (SYS.NAME_UNIQUE) violated
-- 插入不同複合值:張學友
INSERT INTO unique_test (id, fname, lname) VALUES (2, '學友', '張'); -- 成功
-- 插入 NULL email (兩筆皆無 email)
INSERT INTO unique_test (id, fname, lname, email) VALUES (3, 'A', 'B', NULL); -- 成功
INSERT INTO unique_test (id, fname, lname, email) VALUES (4, 'C', 'D', NULL); -- 成功! 不違反 UNIQUE
NULL 代表「值不存在」,不參與相等比較NULL 不違反 UNIQUE 約束CHECK 約束或虛擬欄位 (11g+)-- 查看表的所有約束
SELECT constraint_name, constraint_type, search_condition, status
FROM user_constraints WHERE table_name = 'UNIQUE_TEST';
-- 查看約束包含欄位
SELECT constraint_name, column_name, position
FROM user_cons_columns WHERE table_name = 'UNIQUE_TEST';
-- 停用 (大量載入資料時)
ALTER TABLE unique_test DISABLE CONSTRAINT email_unique;
-- 啟用並驗證現有資料
ALTER TABLE unique_test ENABLE VALIDATE CONSTRAINT email_unique;
-- 僅啟用不驗證現有資料 (風險自負)
ALTER TABLE unique_test ENABLE NOVALIDATE CONSTRAINT email_unique;
-- 刪除約束
ALTER TABLE unique_test DROP CONSTRAINT email_unique;
| 特性 | PRIMARY KEY | UNIQUE |
|---|---|---|
| 每張表數量 | 僅一個 | 可多個 |
| 允許 NULL | 不允許 | 允許 (多筆) |
| 預設索引 | 唯一索引 | 唯一索引 |
| 外鍵參考 | 可被參考 | 可被參考 |
UK_表名_欄位 或 UK_表名_欄位1_欄位2DISABLE 約束,匯入後 ENABLE VALIDATE,效能提升數倍DBA_CONSTRAINTS.STATUS = 'DISABLED' 異常狀態正確使用 UNIQUE 約束是防止髒資料、保障業務鍵唯一性的第一道防線。