【问题标题】:Incorrect syntax near 'case', 'when' and 'end' in CASE statementCASE 语句中“case”、“when”和“end”附近的语法不正确
【发布时间】:2014-07-15 17:27:38
【问题描述】:

我在我的案例陈述中遇到了错误。现在,在我参与的项目中使用它之前,我正在针对 NorthWind DB 对其进行测试。 我知道我应该使用 IF/ELSE,它适用于 IF/ELSE,唯一的问题是我必须在函数中执行此操作,而不是使用存储过程。 据我了解,在使用表值函数时我必须使用 case 语句,因为函数只能包含一个语句,因此需要使用 case,并且有人告诉我,我对 IF/ELSE 所做的是函数不允许这种类型的逻辑..

我将与@PreAQ 一起传递一个 ID,它只会返回基于过滤器的记录,这些过滤器类似于下面看到的过滤器,但有多个 LIKES。

declare @PreAQ int
set @PreAQ = 0

case 
when @PreAQ = 0
    then
        (select * from Contacts where CompanyName like 'An%')
when @PreAQ = 1 
    then 
        (select * from Contacts where ContactTitle like 'S%')
end 

抛出的错误是

消息 156,级别 15,状态 1,第 7 行 关键字“case”附近的语法不正确。

消息 156,级别 15,状态 1,第 11 行 关键字“when”附近的语法不正确。

消息 102,级别 15,状态 1,第 14 行 'end' 附近的语法不正确。

我也试过了……

case @PreAQ
when  = 0
    then...

然后我得到同样的错误

编辑

这与我的函数将在工作中执行的操作类似(除了过滤器和表格不同,但这仍然使用 NorthWind 作为测试数据库,请注意如何取决于“@PreAQ”编号,我需要它运行语句。我正在尝试这样做...

declare @PreAQ int
set @PreAQ = 0

case
when @PreAq 0
    then
(select * from [Contacts]
where (CompanyName like 'An%' 
or CompanyName like 'B%'
or CompanyName like 'Ch%'
or CompanyName like 'De%'
or CompanyName like 'F%'))

 when @PreAQ 1
then
 (select * from [Contacts]
 where (CompanyName like 'Wa%' 
or CompanyName like 'Be%'
or CompanyName like 'Y%'
or CompanyName like 'DeF%'
or CompanyName like 'Fa%'
or CompanyName like 'Me%'
or CompanyName like 'Ma%'))
 end

【问题讨论】:

  • 想一想:有了函数,就提前知道了返回的表结构。如果允许您根据参数从具有不同结构的两个不同表中返回,这将如何工作?
  • @hvd,你是对的。我做了一个编辑,所以它来自同一张桌子。这应该可以消除任何误解。在项目中它将使用一个特定的表,现在测试代码反映了这一点。我不是sql高手,从来没用过CASE或者函数,用过存储过程,但是不会用
  • 哪个 RDBMS?语法各不相同。我认为您需要最后一个版本,但像这样:case @PreAQ when 0 then ...(无 =)。
  • @Turophile,MS SQL2012。我也尝试过这种方式并得到相同类型的错误(我确实省略了 = 符号)
  • 啊,SQL-Server?然后你需要something = CASE WHEN x=y THEN a WHEN x=w THEN b ELSE c END。在您的简单示例中,设置变量 @match 并使用单个 SQL 语句 select * from Contacts where ContactTitle like @match 会更容易。

标签: sql sql-server-2012 logic sql-function


【解决方案1】:

如果你想创建内联表值函数,你可以使用这样的东西:

create function dbo.ufn_SomeFunction(@PreAQ int)
  returns table
return 
(select * from Contacts
  where (case when @PreAQ = 0 then CompanyName else ContactTitle end)
     LIKE (case when @PreAQ = 0 then 'An%' else 'S%' end) )

注意,您将进行表/聚集索引扫描。

【讨论】:

  • 我知道你打算用这个去哪里,但“@PreAQ”的范围是 0 - 2,取决于哪个数字“@PreAQ”将决定表格上的过滤器。 0 将有 5 个过滤器,1 将有 7 个过滤器,2 将应用 12 个过滤器。也许我应该编辑我的问题并发布我正在处理的“实时”功能而不是测试代码?
  • 我什至不能发布代码,它在工作..所以我被测试代码卡住了
【解决方案2】:

如果您的 SQL 语句变化如此之大,您可能需要使用动态 SQL,使用 SP_EXECUTESQL 执行。有关示例,请参阅此 SO 问题:Dynamic SQL Server stored procedure

【讨论】:

  • 如果您建议我使用存储过程,如果我错了,请原谅我(因为从链接来看,它看起来像一个存储过程),我希望我可以那样我不会'没有问题。它是我必须创建的功能
【解决方案3】:

这应该可行,但我同意动态 SQL 会是更好的方法。

    declare @PreAQ int
    set @PreAQ = 1

    select *
    from Contacts
    where (
            CompanyName like case @PreAQ
            when 0 then 'An%'
            end
         or ContactTitle like case @PreAQ
            when 1 then 'S%'
            end
          )

【讨论】:

    【解决方案4】:

    在 SQLServer 的 TSQL 中,CASE 不是用于控制执行哪段代码的编程构造,而是始终返回单个数据值的expression

    试试IF...ELSE

    if @PreAQ = 0
       select * from Contacts where CompanyName like 'An%'
    else if @PreAQ = 1
       select * from Contacts where ContactTitle like 'S%'
    

    【讨论】:

    • 我尝试使用 IF 语句,但它从未在函数中工作,但是我对此有一个解决方案,并将在今天晚些时候发布,有几个不同的解决方案。
    猜你喜欢
    • 1970-01-01
    • 2011-10-27
    • 1970-01-01
    • 2013-08-02
    • 1970-01-01
    • 2013-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多