我在这里阅读了有关在WHERE子句中使用CASE表达式的内容:
http://scottelkin.com/sql/using-a-case-statement-in-a-sql-where-clause/
我正在尝试使用它来根据用户应用程序传递的合同号来过滤select语句的结果。我的代码当前抛出了'无效参数'的错误,无论传入什么。我验证SELECT / FROM工作正常,如没有CASE表达式的WHERE子句。这是我的代码。
WHERE (CASE WHEN @ContractNo = 0 THEN @ContractNo ELSE @ContractNo END =
tblContracts.ContractNo)
代码的冗余用于故障排除,我打算稍后在CASE上使用通配符过滤。我正专注于立即降低语法。我相信这应该返回参数与表中存储的合同号匹配的所有记录。任何帮助或建议将不胜感激。
答案 0 :(得分:9)
你确定要这么做吗?您的案例陈述总是返回@ContractNo
。我认为你在寻找的是:
where
case @ContractNo
when 0 then tblContracts.ContractNo
else @ContractNo
end = tblContracts.ContractNo
上面的过滤器显示“给我ContractNo
等于参数的合同,或者如果参数为0,则为所有合同。
仅过滤合约编号字段与参数完全相同的前一过滤器。
无论如何,你应该这样做:
where @ContractNo = 0 or @ContractNo = tblContracts.ContractNo
逻辑更容易理解,除此之外(不要引用我),优化器可能会在case语句之外更好地工作。
答案 1 :(得分:7)
阅读完解释后,有一种更好的方法可以在没有CASE
的情况下执行此操作:
WHERE @ContractNo = 0 OR tblContracts.ContractNo = @ContractNo
这将只返回匹配的合同号,除非@ContractNo
为0,在这种情况下它将返回所有记录。
编辑:我刚刚注意到casperOne proposed the same thing。我没有看到。大自己。
答案 2 :(得分:2)
尽量忽略错误位置的括号 - 正确的括号应该在“结束”之后。
答案 3 :(得分:2)
也许你忘了宣布@ContractNo?它是否与0和tblContracts.ContractNo?
相当答案 4 :(得分:1)
将你的右括号移到=之前,如下所示:
WHERE (CASE WHEN @ContractNo = 0 THEN @ContractNo ELSE @ContractNo END)=tblContracts.ContractNo
我没看到这个案例陈述会做什么但是......如果@ContractNo = 0或者它不是......那么你将返回相同的东西......
正确的语法是:
Select...
...
Where(
Case
When <Condition>
Then <Return if true>
Else <Return if false>
End
) = <Whatever is being matched to the output of the case statement>
无论语法如何,你的例子没有多大意义,如果你正在寻找所有匹配或者合同号为0的项目,那么你会这样做:
Select...
...
Where (
@ContractNo = 0 Or
@ContractNo = tblContracts.ContractNo
)
这似乎比你试图使用case语句更有意义。
编辑:我一定是误解了这个问题 - 缺少的参数通常意味着参数(在本例中为@ContractNo)未在查询/过程的范围内声明。但有人已经指出了这一点,所以我不能相信这一点。
答案 5 :(得分:1)
case语句的原因,包括整个“If it为0,给出参数,否则,只给出参数”是为了测试它以试图使语法正确。最初,我试过说“如果它是0,然后传入'%',返回每个值。我在那里发布的代码是因为我一直得到'无效参数'并且认为我的语法一定有问题。我将它分成基本参数匹配,如此,
WHERE @ContractNo = tblContracts.ContractNo
它恢复了记录。让我解释一下。
我从一堆不同的表中提取,并使用未包含在select语句中的信息过滤内容(即tblContracts没有通过Select从中提取信息,它仅在Where中使用)。用户将从具有不同合同号的组合框中进行选择,以及默认值“全部”。
当组合框的索引发生变化时,我将发生一个事件。如果它是'All',0将作为参数传入,我不想进行过滤。否则,我只想要该合同号的信息(Else @ContractNo的原因)。
答案 6 :(得分:1)
Recursive的帖子正好解决了我的问题。
我看到有关我原帖的清晰度的投诉。在未来,我能做些什么才能让我说的更直接?我不习惯于对代码的问题进行措辞,并为任何混乱的事情道歉。我是否只需要在第二篇文章中提供扩展的详细信息?
再次感谢您的帮助。
答案 7 :(得分:0)
你的意思不是这样的吗?
SELECT *
FROM tblContracts
WHERE
CASE
WHEN tblContracts.ContractNo = 0 THEN @ContractNo
ELSE tblContracts.ContractNo
END = tblContracts.ContractNo
其中@ContractNo是与tblContracts.ContractNo相同的数据类型的变量
答案 8 :(得分:0)
为什么你甚至需要一个案例陈述?
当@ContractNo = 0然后(0 = tblContracts.ContractNo) 否则@ContractNo(@ContractNo = tblContracts.ContractNo)
这没有任何意义,因为您可以简单地将其写为
其中@contractNo = tblContracts.contractNo
答案 9 :(得分:0)
合约编号实际上是数字还是字符串总是恰好是数字。检查表与参数和CASE语句之间的数据类型(例如,“= 0”或“='0'”)
答案 10 :(得分:0)
此语法应该有效(在Oracle中有效)
WHERE CASE WHEN tblContracts.ContractNo = 0
THEN @ContractNo
ELSE tblContracts.ContractNo
END = tblContracts.ContractNo
答案 11 :(得分:0)
当你说:
我从一堆不同的表中提取,并使用未包含在select语句中的信息过滤内容(即tblContracts没有通过Select从中提取信息,它仅在Where中使用)。用户将从具有不同合同号的组合框中进行选择,以及默认值“全部”。
然后我觉得应该有一个“Where exists”条款。既然你没有从那张桌子中取出任何信息?!