仅当变量不为null时,SQL才会添加过滤器

use*_*872 12 sql sql-server

嗨,我有如下查询:

    SELECT  route_id [ROUTE_ID]
    FROM route_master(NOLOCK)
    WHERE  route_ou = 2
    AND   route_query = @l_s_query
    AND   lang_id  = 1
Run Code Online (Sandbox Code Playgroud)

这里,只有当@l_s_query为非空时,才应添加WHERE子句中的"AND route_query = @l_s_query"条件.我不想为@l_s_query写IF IFSE条件.有没有办法直接处理WHERE子句本身.谢谢.

sag*_*agi 13

您可以将您的要求转换为:

SELECT  route_id [ROUTE_ID]
FROM route_master(NOLOCK)
WHERE  route_ou = 2
AND   (@l_s_query is null OR route_query = @l_s_query)
AND   lang_id  = 1
OPTION (RECOMPILE)
Run Code Online (Sandbox Code Playgroud)

OPTION (RECOMPILE)是可选的,但可以牺牲额外的编译时间来提供更好的执行计划,如关于T-SQL中动态搜索条件主题的规范性文章中所讨论的那样

或者COALESCE()避免OR:

WHERE  route_ou = 2
AND   COALESCE(@l_s_query,route_query) = route_query 
AND   lang_id  = 1
Run Code Online (Sandbox Code Playgroud)

注意:正如@jarlh所说,如果可以route_query为空,这可能会导致一些问题,因为null比较,所以你可能想要使用第一个查询.

另一个选择是两个单独的查询使用UNION ALL,每个条件一个 -

SELECT .. FROM .. 
WHERE @l_s_query IS NULL
UNION ALL
SELECT .. FROM .. 
WHERE @l_s_query = route_query
Run Code Online (Sandbox Code Playgroud)

在性能方面,只有最后一个将使用索引,我相信第一个将是最快的,但它可能会改变对表的ETC的索引,大小的去除.