SQL:取消null参数的'where'

时间:2011-01-20 10:11:51

标签: sql tsql

这可能很明显,但我很困惑。

我有一个带有where子句的SQL查询(其中包含参数列表)。如果所有这些参数都为null,我需要SQL忽略where子句并检索所有记录。在SQL中这很容易吗?我知道一种方法是,如果参数为null,只需使用代码删除where子句。

6 个答案:

答案 0 :(得分:5)

最高效的方法是根本不包含WHERE条款,如果这是你的选择。

您经常会看到使用WHERE X=@X OR @X IS NULL等技巧,但如果您传递@X

的特定值,这些技巧会导致次优计划和不必要的表扫描

编辑:

由于这个答案似乎遇到了一些意想不到的怀疑......

create table #t
(
id varchar(5) primary key /*varchar to test LIKE without causing any casts*/
)

INSERT INTO #t
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 0))
FROM sys.all_columns


SET STATISTICS IO ON
/*Test the equals */

EXEC sp_executesql N'
SELECT * 
FROM #t
WHERE (@id IS NULL OR id = @id)', N'@id varchar(5)', @id='1'

/*Is `LIKE` any better? */

EXEC sp_executesql N'
SELECT * 
FROM #t
WHERE (@id IS NULL OR id LIKE @id)', N'@id varchar(5)', @id='1'

/*What should the plan look like? */

EXEC sp_executesql N'
SELECT * 
FROM #t
WHERE (id = @id)', N'@id varchar(5)', @id='1'

DROP TABLE #t

Execution Plans

答案 1 :(得分:5)

您可以尝试这样做:

select *
from foo
where (@parameter1 is null AND @parameter2 is null)
OR  (@parameter1 = 'value1'
    AND
    @parameter2 = 'value2')

在你自己的查询中需要进行一些调整,但现在你将检查参数是否为null或者是否使用原始where子句。

答案 2 :(得分:1)

如果它是一个存储过程,要么使用动态SQL,要么在参数为空时根本不附加where子句,或者仍然使用IF ELSE并在IF和其他一个中写入查询两次在哪里和哪一个没有,我同意马丁的意见,如果应该检索所有记录,应该完全避免在哪里。

答案 3 :(得分:1)

...
WHERE
    (
        col1 IS NULL
        AND col2 IS NULL
        AND col3 IS NULL
    ) OR
    (
        conditions...
    );

答案 4 :(得分:1)

在这里查看符合您要求的文章handling-optional-parameters。本文比较了执行可选参数的各种方法,并讨论了不同版本的SQL Server以及每种版本的性能。

我认为你所追求的是每列IS NULL + OR,对吗?

WHERE (@col1 IS NULL OR col1 LIKE @col1)
  AND (@col2 IS NULL OR col2 = @col2)

答案 5 :(得分:1)

我真的认为这会起作用

    Where ((CASE WHEN @Parameter1 is null then 1 else 0 end) = 1 and 
   (CASE WHEN @Parameter2 is null then 1 else 0 end) = 1)