【问题标题】:CASE statement construction with parameter带参数的 CASE 语句构造
【发布时间】:2017-11-23 15:49:24
【问题描述】:

谁能告诉我,下面的结构有什么问题?:

 CASE @CountryID
        WHEN 1 THEN SET @String = REPLACE(@String,'+420','')
        WHEN 2 THEN SET @String = REPLACE(@String,'+421','')    
        WHEN 3 THEN SET @String = REPLACE(@String,'+359','')    
        WHEN 4 THEN SET @String = REPLACE(@String,'+7','')  
        WHEN 5 THEN SET @String = REPLACE(@String,'+48','') 
        WHEN 7 THEN SET @String = REPLACE(@String,'+63','') 
    END

@CountryIDINT

问题出在 CASE 语句构造中,因为 IF 语句运行良好,但我看不到任何磨损并尝试了不同类型的案例构造并搜索了文档。

任何提示将不胜感激。

【问题讨论】:

    标签: sql sql-server tsql case


    【解决方案1】:

    你需要使用:

    SELECT @String = 
    CASE @CountryID
            WHEN 1 THEN REPLACE(@String,'+420','')
            WHEN 2 THEN REPLACE(@String,'+421','')    
            WHEN 3 THEN REPLACE(@String,'+359','')    
            WHEN 4 THEN REPLACE(@String,'+7','')  
            WHEN 5 THEN REPLACE(@String,'+48','') 
            WHEN 7 THEN REPLACE(@String,'+63','') 
            -- ELSE @String  -- to avoid NULL if no country found
        END;
    

    CASE is expression,但您将其用作 CASE statement(例如在 Oracle/DB2 中可用)


    Oracle 同时支持CASE statementT-SQL 中不可用):

    CASE
        WHEN jobid = 'PU_CLERK' THEN sal_raise := .09;
        WHEN jobid = 'SH_CLERK' THEN sal_raise := .08;
        WHEN jobid = 'ST_CLERK' THEN sal_raise := .07;
        ELSE sal_raise := 0;
      END CASE;
    

    CASE expression

     appraisal :=
          CASE grade
             WHEN 'A' THEN 'Excellent'
             WHEN 'B' THEN 'Very Good'
             WHEN 'C' THEN 'Good'
             WHEN 'D' THEN 'Fair'
             WHEN 'F' THEN 'Poor'
             ELSE 'No such grade'
          END;
    

    编辑:

    正如HABO 提到的,您可以将其重写为:

    SELECT @String = REPLACE(@String, 
        CASE @CountryID
                WHEN 1 THEN '+420'
                WHEN 2 THEN '+421' 
                WHEN 3 THEN '+359'  
                WHEN 4 THEN '+7'
                WHEN 5 THEN '+48'
                WHEN 7 THEN '+63'
                ELSE ''
            END, '');
    

    或者在 SQL Server 2012 及更高版本中,您可以使用CHOOSE

    SELECT @String = 
      REPLACE(@String, CHOOSE(CountryId,'+420','+421','+359','+7','+48', '+63'), '')
    

    【讨论】:

    • +1 虽然我会在我的答案(当我看到你的答案时开始写)中包括在 SQL Server 中,case 不能用作流控制。我猜只是说它是一种表达方式可能很多人都无法理解。
    • @ZoharPeled 添加了来自 Oracle 的版本来说明它。
    • 如果所有情况都涉及删除子字符串,则可以移动逻辑以选择目标:Replace( @String, case @CountryId when 1 then '+420' when 2 then '+421' when ... end, '' )。您可以添加else '' 以默认返回原始字符串。
    • @HABO 感谢您的想法。
    【解决方案2】:

    @lad2025 重写了有效的代码(以及一个很好的解释!)。我想指出,在 SQL Server 中,我更喜欢:

    SELECT @String = REPLACE(@String, v.str, '')
    FROM (VALUES (1, '+420'), (2, '+421'), (3, '+359'), (4, '+7'),
                 (5, '+48'), (7, '+63')
         ) v(countryId, str)
    WHERE v.countryId = @CountryID;
    

    如果没有匹配,我认为这不会改变@String 的值。

    【讨论】:

    • 你能告诉我这个特性在 SQL Server 中被称为什么,你可以像在你的解决方案中那样在旅途中创建一个表吗? (值 (1, '+420'), (2, '+421'), (3, '+359'), (4, '+7'), (5, '+48'), (7, '+63') ) v(countryId, str)
    • @Nitin_g3 。 . .它被称为表值构造函数docs.microsoft.com/en-us/sql/t-sql/queries/….
    猜你喜欢
    • 1970-01-01
    • 2021-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-10
    • 1970-01-01
    • 2021-10-10
    相关资源
    最近更新 更多