我想创建一个存储过程。如果参数为-1,那么该列上不应该有where子句,否则应该有一个WHERE子句。如果没有大量的IF分支,最好的方法是什么?
我查了档案。有几个类似的问题,但不完全相同。
CREATE PROCEDURE report
(
@site int,
@promo int,
@type int
)
AS
SET NOCOUNT ON
-- I want to avoid this:
IF @site = -1 AND @promo = -1 and @type = -1
BEGIN
SELECT * from table
END
IF @site > -1 AND @promo = -1 and @type = -1
BEGIN
SELECT * from table WHERE site = @site;
END
... -- other cases
ELSE -- all parameters are > -1
BEGIN
SELECT * from table
WHERE site = @site AND promo = @promo AND type = @type
END
答案 0 :(得分:3)
这在许多情况下都适用(尽管评论会说没有尝试),因为优化器会忽略ISNULL位。仅适用于非空列
SELECT @site = NULLIF(@site, -1) ...
SELECT * from table
WHERE site = ISNULL(@site, site) ..
否则,条件WHERE通常是坏的,因为OR无法优化
SELECT * from table
WHERE (@site = -1 OR site = @site) AND (...
或单独的存储过程(不要以为你想要那个)
或者使用sp_executesql(避免使用动态SQL)
答案 1 :(得分:1)
怎么样:
SELECT * FROM table WHERE
((site = @site) OR (@site = -1)) AND
((promo = @promo) OR (@promo = -1)) AND
((type = @type) OR (@type = -1))
但是,有一点需要注意,您可能会发现SQL在优化此类查询时并不是非常聪明。
答案 2 :(得分:1)
为什么要与明显的,最简单的解决方案作斗争?
严重的是,分支解决方案使意图明确,并且其他人可以轻松理解。