面對多個可選查詢條件(如日期、姓名),常見三種實作模式:分支判斷、動態拼接、邏輯合併。本文比較優劣並推薦最佳寫法。
@addDate(日期)、@name(姓名)IF @addDate IS NOT NULL AND @name <> ''
SELECT * FROM tbl WHERE addDate = @addDate AND name = @name
ELSE IF @addDate IS NOT NULL AND @name = ''
SELECT * FROM tbl WHERE addDate = @addDate
ELSE IF @addDate IS NULL AND @name <> ''
SELECT * FROM tbl WHERE name = @name
ELSE
SELECT * FROM tbl
缺點:條件數 n 時需 2ⁿ 分支,維護困難、程式碼膨脹、計畫快取碎片化。
DECLARE @sql NVARCHAR(MAX) = 'SELECT * FROM tbl WHERE 1=1'
IF @addDate IS NOT NULL SET @sql += ' AND addDate = @addDate'
IF @name <> '' SET @sql += ' AND name = @name'
EXEC sp_executesql @sql, N'@addDate DATE, @name NVARCHAR(50)', @addDate, @name
優點:靈活、計畫可重用(參數化)。
缺點:需防 SQL 注入、除錯困難、權限要求高、易寫錯語法。
SELECT * FROM tbl
WHERE (@addDate IS NULL OR addDate = @addDate)
AND (@name = '' OR name = @name)
優點:單一陳述式、計畫穩定、可讀性高、無注入風險、優化器易產生最佳計畫。
適用性:SQL Server、MySQL、PostgreSQL、Oracle 皆支援。
CREATE INDEX IX_tbl_addDate_name ON tbl(addDate, name) INCLUDE(其他常查欄位)邏輯合併寫法在參數為 NULL 時,優化器可能掃描全表。若資料量極大且頻繁全表掃描,可考慮:
OPTION (RECOMPILE) 強制依參數值重新編譯原則:優先用邏輯合併,效能不足再優化,別過早複雜化。