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

时间:2016-08-08 11:38:59

标签: 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

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

5 个答案:

答案 0 :(得分:12)

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

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)

OPTION (RECOMPILE)是可选的,但可以牺牲额外的编译时间来提供更好的执行计划,正如关于该主题Dynamic Search Conditions in T‑SQL的规范性文章中所讨论的那样

COALESCE()以避免OR

WHERE  route_ou = 2
AND   COALESCE(@l_s_query,route_query) = route_query 
AND   lang_id  = 1

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

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

SELECT .. FROM .. 
WHERE @l_s_query IS NULL
UNION ALL
SELECT .. FROM .. 
WHERE @l_s_query = route_query

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

答案 1 :(得分:2)

  &#34>&​​#34; AND route_query = @ l_s_query"仅当@l_s_query为非空时才应添加WHERE子句中的条件。

FullArgs

答案 2 :(得分:1)

您可以使用OR:

模拟if-else
AND ((0 = len(@l_s_query) OR @l_s_query IS NULL OR route_query = @l_s_query)

说明:

  • AND (...) - 括号必须仅对此谓词应用非空检查
  • 0 < len(@l_s_query) - 是一种确定varchar - s的非空虚的方法。

答案 3 :(得分:0)

SELECT  route_id [ROUTE_ID]
FROM route_master(NOLOCK)
WHERE  route_ou = 2
AND   (route_query = @l_s_query AND @l_s_query IS NOT NULL)
AND   lang_id  = 1

答案 4 :(得分:0)

以下是一种更好的处理方式:使用LEN(ISNULL)... OR

AND (LEN(ISNULL(@l_s_query,'')) = 0 OR route_query = @l_s_query)