SQL存储过程参数非空时如何高效向WHERE子句追加筛选条件
方案1:单查询条件判断(写法最简单,适合中小数据量)
直接在现有WHERE子句中追加参数非空的判断逻辑即可:
WHERE ([LoggedIn] >= @dateFrom AND [LoggedIn] <= @dateTo) AND (@email IS NULL OR [Email] = @email)
如果你的业务逻辑里空字符串也算「@email参数为空」的情况,调整判断条件就行:
AND (@email IS NULL OR @email = '' OR [Email] = @email)
如果表数据量较大、且查询频率高,可以在语句末尾加OPTION (RECOMPILE),让SQL每次执行都根据当前参数生成最优执行计划,避免参数嗅探导致索引失效。
方案2:动态参数化SQL(性能最优,适合大数据量高频查询)
这是生产环境大表场景的最优选择,完全不会引入多余的查询判断逻辑,执行计划可以完美匹配现有索引,同时参数化传值也完全规避了SQL注入风险:
DECLARE @QuerySQL NVARCHAR(MAX) -- 拼接基础查询逻辑,不要写SELECT *,替换为你实际需要的查询字段 SET @QuerySQL = N' SELECT 字段1,字段2... FROM 你的业务表名 WHERE ([LoggedIn] >= @dateFrom AND [LoggedIn] <= @dateTo)' -- 仅当@email非空时拼接邮箱筛选条件 IF @email IS NOT NULL AND @email <> '' BEGIN SET @QuerySQL = @QuerySQL + N' AND [Email] = @innerEmail' END -- 执行动态SQL,参数绑定 EXEC sp_executesql @QuerySQL, N'@dateFrom DATETIME, @dateTo DATETIME, @innerEmail VARCHAR(255)', -- 此处参数类型要和你存储过程定义的参数类型完全一致 @dateFrom = @dateFrom, @dateTo = @dateTo, @innerEmail = @email
选型建议
如果你的表数据量在十万以下、查询频率低,选方案1即可,写起来更省事;如果数据量超过十万、或者这个存储过程调用频率很高,优先选方案2,性能优势会非常明显。
内容的提问来源于stack exchange,提问作者DarkW1nter
相关产品推荐
相关产品推荐

