如果位参数= 0,则SQL Server返回字段值为0或null的记录

时间:2018-08-28 20:06:56

标签: sql sql-server where-clause resultset

我有一个大型存储过程(超过500行),从中返回了运营商记录。我在调用此存储过程时将值传递给的参数之一将在where子句中使用以过滤结果集。这是一个位类型参数,由我的实体模型(Web API)中的布尔属性表示。

我无法弄清楚如何构造where子句以返回结果集中的相应记录。

这是我想要发生的事情的基本轮廓:

  1. 如果位类型参数为NULL,请返回所有记录
  2. 如果位类型参数等于1,则返回指定位类型字段值为1的所有记录
  3. 如果位类型参数等于0,则返回所有指定位类型字段为null或值为0的记录

我的尝试是出于上下文(请原谅,我不是一个强大的SQL开发人员):

DECLARE @Intrastate bit;
SET @Intrastate = 0; --should return all records where Intrastate field
                     --is null or has a value of 0
SELECT * FROM Carriers c
    WHERE @Intrastate IS NULL
        OR c.Intrastate = CASE WHEN @Intrastate = 1 THEN @Intrastate END
        OR c.Intrastate = CASE WHEN @Intrastate = 0 THEN @Intrastate END
        OR c.Intrastate = NULLIF(@Intrastate, 0)

上面的查询仅返回Intrastate字段值为0的记录,不包括Intrastate字段为null的记录。

DECLARE @Intrastate bit;
SET @Intrastate = 0; --should return all records where Intrastate field
                     --is null or has a value of 0
SELECT * FROM Carriers c
    WHERE @Intrastate IS NULL
        OR c.Intrastate = CASE WHEN @Intrastate = 1 THEN @Intrastate END
        OR c.Intrastate in (SELECT DISTINCT Intrastate FROM Carriers
                                WHERE Intrastate = 0
                                    OR Intrastate IS NULL)

同样,上述查询仅返回Intrastate字段值为0的记录,不包括Intrastate为null的记录。

NULL1分配给@Intrastate参数会产生所需的结果集,如上所述。

我的问题仅是当@Intrastate参数的值为0时返回结果集。

任何人和所有帮助都将受到高度赞赏。

3 个答案:

答案 0 :(得分:3)

那......

...
WHERE @Intrastate IS NULL
OR ISNULL(c.Intrastate, 0) = @Intrastate

这样,如果变量为null,则将获取所有记录;如果不是,则将列合并为0(如果为null),则该列应覆盖1 = 1和0 = 0 / null = 0。

答案 1 :(得分:1)

如果您将ANSI_NULLS设置为

,则此方法有效
SET ANSI_NULLS Off
GO
WHERE Intrastate in (isnull(@Intrastate,Intrastate), nullif(isnull(@Intrastate,0), 0))

答案 2 :(得分:0)

好的,此解决方案看起来很麻烦,但是如果WHERE子句中有function on the predicate column,则sql server最有可能扫描整个表而不使用索引:

SELECT * FROM Carriers c
WHERE @Intrastate IS NULL
      OR (@Intrastate = 1 AND c.Intrastate = 1)
      OR ( @Intrastate = 0 AND (  c.Intrastate IS NULL 
                                  OR c.Intrastate = 0 ))