如果参数为null或返回所选值,请选择all

时间:2018-01-31 11:14:09

标签: sql sql-server

我有下表(仅供参考,原始表有数千条记录):

+-------+------------+--------+
| Brand | Categories | Amount |
+-------+------------+--------+
|  ABC  |  Cat1      | 779    |
|  DEF  |  Cat2      | 543    |
+-------+------------+--------+

我在一个过程中创建一个temp table,如果参数匹配,则会拉取值。

create proc PROCNAME @Brand nvarchar(max), @Category nvarchar(max) as

create table #table1(VALUES)
insert into #table1(VALUES)
select amount 
from OriginalTable
where @Brand in (Select value from fn_split(@Brand,',')) or @Brand is null
and @Category in (Select value from fn_split(@Category,',')) or @Category is null

fn_split传递逗号分隔值。

我需要一些东西,如果参数传递一个空值,那么它将SELECT ALL它们的值,否则传递任何东西。

我知道我用于is null条件的代码是错误的,但任何帮助都将受到赞赏。

3 个答案:

答案 0 :(得分:1)

我会使用动态SQL执行此操作:

create proc PROCNAME 
    @Brand nvarchar(max)
  , @Category nvarchar(max) 
AS
BEGIN
    SET NOCOUNT ON;
    Declare @Sql NVARCHAR(MAX);

create table #table1(VALUES)

SET @sql = N'insert into #table1(VALUES)
             select amount 
             from OriginalTable
             where 1 = 1 ' 
        + CASE WHEN @Brand IS NOT NULL THEN 
            N' AND Brand in (Select value from fn_split(@Brand,'','')) ' ELSE N'' END
        + CASE WHEN @Category IS NOT NULL THEN 
            N' AND Category in (Select value from fn_split(@Category,'',''))' ELSE N'' END

Exec sp_executesql @sql
                  , N'@Brand nvarchar(max) , @Category nvarchar(max)'
                  , @Brand
                  , @Category
END
GO

其他方法的问题

这种其他方法存在一个主要问题,你可以在where where子句中编写类似......

的内容
WHERE ( Brand = @Brand  OR @Brand is null)

这种方法的两个主要问题

1)你不能强制SQL Server首先检查一个表达式,就像@Brand is null一样,Sql Server可能决定先评估表达式Brand = @Brand,这样你就可以对where子句进行求值,即使变量也是如此value为null。

2)SQL Server不执行Short-Circuiting,即使它决定先检查Brand = @Brand表达式,即使它的计算结果为true,SQL Server仍然可以继续进行评估{{}中的其他表达式1}}子句。

因此,对于像这样的查询,请坚持使用Dynamic Sql。和快乐的日子。

答案 1 :(得分:0)

我认为您需要修改WHERE子句,如下所示

WHERE (@Brand IS NULL OR Brand IN (Select value from fn_split(@Brand,','))) AND 
      (@Category IS NULL OR Category IN (Select value from fn_split(@Category,',')))

答案 2 :(得分:0)

where @Brand in (Select value from fn_split(@Brand,',')) or @Brand is null or @Brand=''
and @Category in (Select value from fn_split(@Category,',')) or @Category is null or @Category= ''
相关问题