SQL Server中如何根据@USER_ID参数值动态设置WHERE子句条件
SQL Server 逗号分隔多选参数动态查询实现方案
方案1:非动态SQL实现(无注入风险,适配所有场景)
直接在WHERE子句中加入短路判断逻辑,参数为NULL时自动跳过筛选条件:
DECLARE @USER_ID NVARCHAR(255) = 'a,b,c' -- 赋值为NULL时可返回全表数据 SELECT * FROM <table_name> WHERE @USER_ID IS NULL OR <col_name> IN ( -- SQL Server 2016及以上版本用内置STRING_SPLIT,低版本替换为自定义的SplitString表值函数 SELECT TRIM(value) FROM STRING_SPLIT(@USER_ID, ',') )
该写法利用SQL的短路求值特性:当@USER_ID为NULL时,第一个判断条件直接成立,数据库不会执行后续的IN逻辑,直接返回全表数据,完全匹配需求。
方案2:动态SQL实现(性能更优,适合大数据量表)
如果查询的表数据量很大,非动态SQL的OR条件可能导致执行计划选优异常,可以用参数化动态SQL实现,同时规避SQL注入风险:
DECLARE @USER_ID NVARCHAR(255) = 'a,b,c' DECLARE @SQL NVARCHAR(MAX) SET @SQL = N'SELECT * FROM <table_name>' IF @USER_ID IS NOT NULL BEGIN SET @SQL = @SQL + N' WHERE <col_name> IN (SELECT TRIM(value) FROM STRING_SPLIT(@USER_ID, '',''))' END -- 参数化执行,避免注入风险 EXEC sp_executesql @SQL, N'@USER_ID NVARCHAR(255)', @USER_ID = @USER_ID
注意事项
- 若需要兼容
@USER_ID为空字符串也返回全表的场景,可将非动态SQL的判断条件改为NULLIF(@USER_ID, '') IS NULL,动态SQL的判断条件改为IF NULLIF(@USER_ID, '') IS NOT NULL - 拆分后的参数值如果存在前后空格,增加
TRIM()处理可以避免匹配失败问题
内容的提问来源于stack exchange,提问作者Peeyush Bansal
相关产品推荐
相关产品推荐

