【问题标题】:SQL Server where clause using iif in store procedure在存储过程中使用 iif 的 SQL Server where 子句
【发布时间】:2018-08-27 15:51:33
【问题描述】:

我在 SQL Server 中有一个存储过程。我的应用程序中有一个过滤页面,我想选择所有CDT_ID,如果我不输入名称以及lower_age和upper_age,它将显示所有CDT_ID。但是如果我输入姓名和年龄,它将显示所有CDT_ID,其中CDT_NAME AND CDT_AGE 范围就像我在过滤列中输入的一样。我的查询如下所示:

select CDT_ID from CANDIDATE 
where CDT_NAME LIKE iif(@name is null, '', @name)
AND CDT_NAME between (iif(@lower_age is null, '', @lower_age) and iif(@upper_age is null, '', @upper_age))

问题是当我执行我的存储过程时,我的查询结果什么也没显示。如果我在没有显示很多CDT_ID 的地方运行查询。你知道如何修复我的“where”子句吗?

【问题讨论】:

    标签: sql sql-server stored-procedures where-clause iif


    【解决方案1】:

    您使用 CDT_NAME 而不是 CDT_AGE。

    我不知道您的确切业务规则,但我不会使用专有的 IIF 或符合标准 SQL 的 COALESCE,而是使用简单的 ORed 条件(这也可能启用索引访问):

    select CDT_ID 
    from CANDIDATE 
    where (@name is null and @lower_age is null and @upper_age is null)
       or (    CDT_NAME LIKE @name
           AND CDT_AGE between @lower_age AND @upper_age
          )
    

    如果您想在 name 或 age 为 null 的情况下返回所有行,您可以将其修改为:

    where (@name is null or @lower_age is null or @upper_age is null)
    

    或者您在选择之前添加一些健全性检查并应用默认值。 或者基于 NULL 运行两个不同的 Select。

    【讨论】:

      【解决方案2】:

      比 IIF,COALESCE 在这里会更好。 此外,在 WHERE 子句中使用参数时,WHERE 子句的典型语法类似于

      ...
      WHERE 1=1 AND p=@param
      

      详情请见this answer

      在您的查询中未提及 CDT_AGE。我冒昧地纠正它。

      这是修改后的查询

      select 
          CDT_ID 
      from CANDIDATE 
      where 
          1=1
              AND
          CDT_NAME LIKE COALESCE(@name,CDT_NAME)
              AND
          CDT_AGE between COALESCE(@lower_age,0) AND COALESCE(@upper_age,1000)
      

      【讨论】:

      • 我强烈反对WHERE 1=1典型语法,即使用于在应用程序中创建动态条件,它仍然只是懒惰。只需添加一个ORed 条件并开始将其包装到()
      猜你喜欢
      • 2014-01-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多