我正在尝试构建一个SQL SP来执行查询报告。它有几个参数可以是NULL或应该有一个值。我正在使用下面的代码。还有另一种替代方法,更干净或更合适。我假设如果Argument为Null,我只会做1 = 1的过滤条件。
DECLARE @Arg1 VARCHAR(10) = NULL,
@Arg2 VARCHAR(10) = NULL
SELECT * FROM Table1
WHERE
(CASE WHEN (@Arg1 IS NULL) THEN
1
ELSE
@Arg1
END) =
(CASE WHEN (@Arg1 IS NULL) THEN
1
ELSE
Location
END)
AND
(CASE WHEN (@Arg2 IS NULL) THEN
1
ELSE
@Arg2
END) =
(CASE WHEN (@Arg2 IS NULL) THEN
1
ELSE
Sex
END)
答案 0 :(得分:4)
你不能这样做吗?
where
(@Arg1 is null or @Arg1 = Location)
and
(@Arg2 is null or @Arg2 = Sex)
然后,如果@Arg1
(或2)为null,那么谓词的那一部分为TRUE
,而and
' d为下一个谓词。
答案 1 :(得分:4)
另一种可能性,即使更短,是使用Coalesce()
:
where COALESCE(@Arg1, Location) = Location
and COALESCE(@Arg2, Sex) = Sex
也就是说,当@ arg1和@ arg2有值时,使用它们,否则,使用有问题的列;因为Location = Location
始终为真(至少在不是NULL时,在您自己的代码中也是同样的问题)。
答案 2 :(得分:1)
另一种可能性是
where IsNull(@Arg1,Location) = Location
and IsNull(@Arg2, Sex) = Sex
这几乎是@IFLoop的答案,但IsNull
略快于COALESCE
。
Which is quicker COALESCE OR ISNULL?
运行以下查询(在我的机器中):
DECLARE @ARG1 VARCHAR(50) = 'xserver_name'
select *
from sys.tables
where IsNull(@Arg1, name) = name
费用:27%
select *
from sys.tables
where Coalesce(@Arg1,name) = name
费用27%
select *
from sys.tables
where (@Arg1 is null or @Arg1 = name)
费用45%
请运行并查看执行计划
但是如果表的行数增加,差异消失,因为是由表扫描时间占主导地位:
select *
from sys.all_Columns
where IsNull(@Arg1, name) = name
费用:33%
select *
from sys.all_Columns
where Coalesce(@Arg1,name) = name
费用34%
select *
from sys.all_Columns
where (@Arg1 is null or @Arg1 = name)
成本33%