[英]How to optionally apply a WHERE IN clause based on a variable?
我有一個存儲過程,需要按以逗號分隔的列表(即'1,2,3'
)傳遞的ID列表進行篩選。
我想應用一個WHERE IN
子句,該子句將與這些id匹配,但僅在變量包含任何內容( IS NOT NULL AND <> ''
) IS NOT NULL AND <> ''
。
這是問題的簡化提琴: http : //sqlfiddle.com/#!18/5f6be/1
目前,它適用於單個和多個ID。 但是,當傳遞''
或NULL
它應該返回所有內容,但不返回任何內容。
出現CTE和分頁的內容是有原因的,請提供一個不會改變它的解決方案。
使用DelimitedSplit8k_lead
您可以通過執行以下操作來達到此目的:
CREATE PROC YourProc @List varchar(8000) = NULL AS
BEGIN
SELECT {YourColumns}
FROM YourTable YT
OUTER APPLY dbo.DelimitedSplit8k_Lead(@List,',') DS
WHERE DS.item = YT.YourColumn
OR NULLIF(@List,'') IS NULL
OPTION (RECOMPILE);
END
使用OUTER APPLY
,就像傳遞NULL
,數據集也不會消除。 RECOMPILE
在那里,因為它變成了“全部捕獲查詢”,並增加了對NULL
的處理。
為什么不在WHERE
子句中使用JOIN
而不是子查詢。
set @userIds = nullif(ltrim(@userIds),'')
select u.*
from Users u
left join string_split(@userIds,',') s on u.Id=s.value
where s.value is not null or @userIds is null
老派的方法:
WHERE
(@userIds IS NULL OR @userIds = '' OR U.Id IN (SELECT * FROM STRING_SPLIT(@userIds, ',')))
最后添加OPTION (RECOMPILE)
,以便工作和調整計划。
編輯:基於注釋,此注釋將生成兩個表掃描。 它對我的LocalDb設置沒有任何影響,但是無論如何都不要依賴它。
WHERE U.Id IN
(
SELECT * FROM STRING_SPLIT(@userIds, ',')
UNION ALL
SELECT U.Id WHERE NULLIF(@userIds, '') IS NULL
)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.