我试图根据某些价值改变某个地方的条件。我在这里看过类似的文章,包括:
SQL Switch/Case in where clause
但他们并没有完全处理我的案子。
我所拥有的是一个基于其输入执行选择的存储过程。这些输入是可选的(或者具有默认参数,因为他们更愿意调用它)。
所述参数中有2个是数字。
这是我尝试的(显然不起作用)
DECLARE @SECOND INT;
DECLARE @FIRST INT;
SET @FIRST = 123456;
SET @SECOND = 67890;
SELECT * FROM BANK_DETAIL
WHERE -- POSSIBLY SOME OTHER WHERE CLAUSES
CASE
WHEN @SECOND IS NULL THEN
X = @FIRST
ELSE
X >= @FIRST AND X <= @SECOND
END
-- POSSIBLY SOME MORE WHERE CLAUSES
ORDER BY X
真的这感觉它需要一个IF / ELSE而不是CASE但是我被引导到CASE .....
哦,这是MS SQL&gt; = 2005
答案 0 :(得分:4)
尝试调整@SECOND的无效性,而不是使用CASE。
SELECT *
FROM BANK_DETAIL
WHERE
-- other conditions go here
AND ((@SECOND IS NULL AND X = @FIRST)
OR (@SECOND IS NOT NULL AND X >= @FIRST AND X <= @SECOND))
答案 1 :(得分:3)
SELECT * FROM BANK_DETAIL
WHERE
(@SECOND IS NULL AND X = @FIRST) or
(X >= @FIRST AND X <= @SECOND)
虽然做得更有效率:
IF @SECOND IS NULL
BEGIN
SELECT * FROM BANK_DETAIL
WHERE
X = @FIRST
END
ELSE
BEGIN
SELECT * FROM BANK_DETAIL
WHERE
X >= @FIRST AND X <= @SECOND
END
答案 2 :(得分:2)
我会使用布尔运算符:
SELECT * FROM BANK_DETAIL
WHERE
((@SECOND IS NULL AND X = @FIRST) OR
(@SECOND IS NOT NULL AND X >= @FIRST AND X <= @SECOND));
答案 3 :(得分:1)
您正在构建dynamic search condition。通过强制一个语句来覆盖两个情况,您正在削减优化器选项。当@seconds
为null且when不为null时,生成的计划必须在两个情况下工作。使用两个单独的声明你会好得多:
IF @SECOND IS NULL THEN
SELECT * FROM BANK_DETAIL
WHERE X = @FIRST
ORDER BY X
ELSE
SELECT * FROM BANK_DETAIL
WHERE X >= @FIRST AND X <= @SECOND
ORDER BY X
你直觉“简化”成一个单一的陈述会导致你走错路。结果是文本较少,但由于计划欠佳,执行时间要长得多。在我的回答开始时链接的文章详细介绍了这一主题。
答案 4 :(得分:0)
问题是CASE
返回一个值,它不是逻辑中的一个分支。 OMG提供的链接几乎是这个链接的权威来源(几乎任何来自Erland Sommarskog的建议都是很好的建议)。
链接的快速摘要:
您可以使用动态SQL,根据条件构建语句。这通常是性能最佳的方法,但也有缺点。最大的缺点之一是可能存在的安全问题,因此请确保您完全了解SQL注入攻击以及如何防止它们。
另一种方法是使用OR在WHERE语句中使用复杂逻辑。在你的情况下,它将类似于下面。这种方法比动态SQL更简单,更安全,但性能可能并不总是很好。如果你的情况表现良好(测试它),那么坚持这种方法。
SELECT
* -- I assume that you used * just as an example and don't actually use this in your production code
FROM
Bank_Detail
WHERE -- POSSIBLY SOME OTHER WHERE CLAUSES
(@second IS NULL AND X = @first) OR
(@second IS NOT NULL AND (x >= @first AND x <= @second))
-- POSSIBLY SOME MORE WHERE CLAUSES
ORDER BY
x
组织声明的另一种方式刚刚发生在我身上......
SELECT
*
FROM
Bank_Detail
WHERE -- POSSIBLY SOME OTHER WHERE CLAUSES
x >= @first AND
x <= COALESCE(@second, @first)
-- POSSIBLY SOME MORE WHERE CLAUSES
ORDER BY
x
我还没有测试过,但我认为这在逻辑上是等效的,可能会为您提供更一致的查询计划。
Erland还提供了其他一些可能的方法,所以一定要阅读他关于这个主题的完整文章。