我在这里阅读了有关在WHERE子句中使用CASE表达式的内容:

http:// scottelkin。 COM / SQL /使用-A-case语句-IN-A-SQL WHERE子句/

我正在尝试使用它来根据用户应用程序传递的合同号来过滤select语句的结果。我的代码当前抛出了'无效参数'的错误,无论传入什么。我验证SELECT / FROM工作正常,如没有CASE表达式的WHERE子句。这是我的代码。

WHERE     (CASE WHEN @ContractNo = 0 THEN @ContractNo ELSE @ContractNo END =
tblContracts.ContractNo)

代码的冗余用于故障排除,我打算稍后在CASE上使用通配符过滤。我正专注于立即降低语法。我相信这应该返回参数与表中存储的合同号匹配的所有记录。任何帮助或建议将不胜感激。

有帮助吗?

解决方案

阅读完解释后,如果没有 CASE ,有更好的方法:

WHERE @ContractNo = 0 OR tblContracts.ContractNo = @ContractNo

这将仅返回匹配的合同号,除非 @ContractNo 为0,在这种情况下它将返回所有记录。

编辑:我刚刚注意到 casperOne提出了同样的建议。我没有看到。大自己。

其他提示

你确定要这么做吗?你的case语句总是返回 @ContractNo 。我认为你在寻找的是:

where 
    case @ContractNo 
        when 0 then tblContracts.ContractNo 
        else @ContractNo 
    end = tblContracts.ContractNo

上面的过滤器说“给我合同,其中 ContractNo 等于参数,或者如果参数为0,则为所有合同。

仅过滤合约编号字段与参数完全相同的前一过滤器。

无论如何,你应该这样做:

where @ContractNo = 0 or @ContractNo = tblContracts.ContractNo

逻辑更容易理解,除此之外(不要引用我),优化器可能会在case语句之外更好地工作。

尝试省略错误位置的括号 - 正确的括号应在“结束”之后。

也许你忘了宣布@ContractNo?它是否与0和tblContracts.ContractNo?

相当

Recursive的帖子正好解决了我的问题。

我看到有关我原帖的清晰度的投诉。在未来,我能做些什么才能让我说的更直接?我不习惯于对代码的问题进行措辞,并为任何混乱的事情道歉。我是否只需要在第二篇文章中提供扩展的详细信息?

再次感谢您的帮助。

将你的右括号移到=之前,如下所示:

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)未在查询/过程的范围内声明。但有人已经指出了这一点,所以我不能相信这一点。

case语句的原因,包括整个“If it为0”,给出参数,否则,只需给出参数“是测试它,试图使语法正确。最初,我试过说“如果它是0,然后传入'%',则返回每个值。我在那里发布的代码是因为我一直收到'无效参数',并认为我的语法一定有问题。当我把它分成像这样的基本参数匹配时,

WHERE @ContractNo = tblContracts.ContractNo

它恢复了记录。让我解释一下。

我从一堆不同的表中提取,并使用未包含在select语句中的信息过滤内容(即tblContracts没有通过Select从中提取信息,它仅在Where中使用)。用户将从具有不同合同号的组合框中进行选择,以及默认值“全部”。

当组合框的索引发生变化时,我将发生一个事件。如果它是'All',0将作为参数传入,我不想进行过滤。否则,我只想要该合同号的信息(Else @ContractNo的原因)。

你的意思不是这样的吗?

SELECT * 
    FROM tblContracts
    WHERE     
    CASE 
       WHEN tblContracts.ContractNo = 0 THEN @ContractNo 
       ELSE tblContracts.ContractNo
    END = tblContracts.ContractNo

其中@ContractNo是与tblContracts.ContractNo相同的数据类型的变量

为什么你甚至需要一个案例陈述?

当@ContractNo = 0然后(0 = tblContracts.ContractNo) 否则@ContractNo(@ContractNo = tblContracts.ContractNo)

这没有任何意义,因为您可以简单地将其写为

其中@contractNo = tblContracts.contractNo

合约编号实际上是数字还是字符串总是恰好是数字。检查表与参数和CASE语句之间的数据类型(例如,“= 0”或“=”0'&quot;)

此语法应该有效(在Oracle中有效)

WHERE CASE WHEN tblContracts.ContractNo = 0 
           THEN @ContractNo 
           ELSE tblContracts.ContractNo
      END = tblContracts.ContractNo

当你说:

  

我从一堆不同的表中提取,并使用未包含在select语句中的信息过滤内容(即tblContracts没有通过Select从中提取信息,它仅在Where中使用)。用户将从具有不同合同号的组合框中进行选择,以及默认值“全部”。

然后听起来应该有一个“存在的地方”。条款。既然你没有从那张桌子中取出任何信息?!

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top