需求:某欄位允許 NULL,但**非 NULL 值必須唯一**。標準 UNIQUE 約束僅允許單一 NULL,不符合需求。本文提供兩種程式化實現方案。
CREATE TABLE t1 (c1 INT NULL, c2 CHAR(5) NULL)
GO
CREATE TRIGGER mytrigger ON t1 FOR INSERT, UPDATE
AS
BEGIN
IF (SELECT MAX(cnt) FROM (
SELECT COUNT(i.c1) AS cnt
FROM t1 JOIN inserted i ON t1.c1 = i.c1
GROUP BY i.c1
) x) > 1
ROLLBACK TRAN
END
Tricks with INSTEAD OF Triggers (InstantDoc 15828)INSTEAD OF Triggers on VIEWs (InstantDoc 15791)INSTEAD OF Triggers (InstantDoc 15524)CREATE UNIQUE INDEX UX_t1_c1_NotNull ON t1(c1) WHERE c1 IS NOT NULL
| 方案 | 適用版本 | 效能 | 維護性 | 推薦度 |
|---|---|---|---|---|
| AFTER TRIGGER | 所有 | 中 | 中 | 舊版本備選 |
| INSTEAD OF TRIGGER | 2000+ | 中 | 高 | 2000/2005 首選 |
| 篩選索引 | 2008+ | 高 | 高 | 現代首選 |
升級至 SQL Server 2008+ 後,請直接使用 CREATE UNIQUE INDEX ... WHERE column IS NOT NULL,最簡潔高效。