我有下表(仅供参考,原始表有数千条记录):
+-------+------------+--------+
| 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
条件的代码是错误的,但任何帮助都将受到赞赏。
答案 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= ''