NULL 在 SQL Server 中代表「未知」而非「空」,處理不當易導致邏輯錯誤。本文針對三大常見情境說明正確作法。
COUNT(欄位):忽略 NULL,僅計算非空值筆數COUNT(*):計算所有列,包含 NULLCOUNT(ISNULL(欄位, 0)) 替換CREATE TABLE xCount (pkey1 INT IDENTITY PRIMARY KEY, Col1 INT NULL)
INSERT xCount (Col1) VALUES (10), (15), (20), (NULL)
SELECT
AVG(Col1) AS AvgWithoutIsNull, -- 15 (忽略 NULL)
AVG(ISNULL(Col1,0)) AS AvgWithIsNull, -- 11 (NULL 視為 0)
COUNT(Col1) AS CntCol1, -- 3
COUNT(ISNULL(Col1,0)) AS CntIsNull, -- 4
COUNT(*) AS CntAll -- 4
FROM xCount
父表主鍵不為 NULL,但子表外鍵允許 NULL 時,DRI(宣告式參考完整性)不會強制子表外鍵必須有對應父表值。此時子表可存入 NULL,導致「孤兒記錄」邏輯上合法但業務上異常。
ALTER TABLE Child
ADD CONSTRAINT CK_Child_Parent_NotNull
CHECK (ParentPkey1 IS NOT NULL)
或允許 NULL 但需驗證:
CHECK (ParentPkey1 IS NULL OR ParentPkey1 IN (SELECT pkey1 FROM Parent))
當父表為複合主鍵(PK1, PK2),子表外鍵允許 NULL 時,可能出現 FK1=有效值, FK2=NULL 的異常組合。需加入多欄位 CHECK 約束:
CHECK (
(FK1 IS NULL AND FK2 IS NULL) OR
(FK1 IS NOT NULL AND FK2 IS NOT NULL AND EXISTS (...))
)
ISNULL/COALESCENOT NULL,業務真正允許「未知」時再放寬正確理解 NULL 語意,配合約束與函數,才能建立資料品質可靠的資料庫系統。