在預存程序中動態拼接 SQL 字串雖然靈活,但帶來嚴重副作用:
IF @addDate IS NOT NULL AND @name <> ''
SELECT * FROM [table] WHERE addDate = @addDate AND name = @name;
ELSE IF @addDate IS NOT NULL AND @name = ''
SELECT * FROM [table] WHERE addDate = @addDate;
ELSE IF @addDate IS NULL AND @name <> ''
SELECT * FROM [table] WHERE name = @name;
ELSE
SELECT * FROM [table];
優點:邏輯清晰、執行計畫最佳化;缺點:條件組合爆炸時程式碼冗長。
SELECT * FROM [table]
WHERE (addDate = @addDate OR @addDate IS NULL)
AND (name = @name OR @name = '');
核心原理:利用 OR @param IS NULL 使條件在參數為 NULL 時自動失效。
注意:字串參數建議用 '' 而非 NULL,避免 NULL = '' 判斷差異。
SELECT * FROM [table]
WHERE addDate = CASE WHEN @addDate IS NULL THEN addDate ELSE @addDate END
AND name = CASE WHEN @name = '' THEN name ELSE @name END;
優勢:語意明確表達「若無輸入則忽略此欄位」;
效能提示:SQL Server 最佳化器通常能將其轉換為方案二的等效計畫。
| 方案 | 適用場景 | 執行計畫重用 | 可讀性 | 維護性 |
|---|---|---|---|---|
| IF-ELSE | 條件 ≤ 3 組合 | 最佳 | 高 | 中 |
| 短路邏輯 | 通用多條件查詢 | 良好 | 高 | 高 |
| CASE 運算式 | 需明確語意表達 | 良好 | 中 | 高 |
OPTION (RECOMPILE) 處理參數嗅探問題(SQL 2008+)ISNULL(addDate, '') = @addDate),導致索引失效掌握這三種模式,即可在不犧牲效能與安全性的前提下,優雅解決預存程序的多條件動態查詢需求。