sql server CASE:将数据类型varchar转换为float时出错

时间:2014-05-12 22:46:57

标签: sql sql-server dynamic case

我正在尝试动态地将一列添加到我的查询中。

我正在运行以下查询:

DECLARE @detMethod varchar(20) = 'MAX(cov)';

WITH myTable as (
                  SELECT user1, (SELECT CASE @detMethod
                                           WHEN 'MAX(cov)' THEN MAX(cov)
                                           ELSE MAX(pcc*cov)
                                        END 
                                ) as method
                  FROM ....
                  WHERE ....
                )

/* some task on myTable */

在这一行上给我一个错误:

SELECT user1, (SELECT CASE @detMethod

Error converting data type varchar to float.

一种可能的替代方法是使用动态sql并将整个查询存储在字符串中,然后使用sp_executesql执行。但这段代码究竟出了什么问题?

编辑:代码没问题,错误在FROM子句中的查询中进一步下降,我没有在CASE块中包含@detMethod。它给我的错误行号是派生表的第一行。

1 个答案:

答案 0 :(得分:2)

我看到两种可能性:

  1. 其中一列covpcc的数据类型为varchar,并且包含无法转换为float的值;
  2. 或者您的查询中的错误会进一步缩小。有时,给出的错误行号不是实际问题表达式的行,而是查询开始的行。既然你指出了一条非常接近查询第一行的行,你就可以一个接一个(如果你的文件顶部附近有一个GO语句就很容易),错误不是用这部分查询。
  3. CASE语句放在SELECT中的模式是不必要的,但这不是导致错误的原因。你可以像这样简化:

    WITH myTable AS (
       SELECT
          user1,
          method = -- Putting the alias first is clearer in my opinion
             CASE @detMethod
                WHEN 'MAX(cov)' THEN MAX(cov)
                ELSE MAX(pcc * cov)
             END
       FROM ...
       WHERE ...
    )
    ...
    

    请注意,使用您选择的CASE语句的备用速记形式没有任何问题,如下所示:

    CASE {expression}
       WHEN {testvalue1} THEN {resultvalue1}
       WHEN {testvalue2} THEN {resultvalue2}
       ...
    END
    

    只要您测试相等性,就不需要完整语法。如果你使用不等式或需要测试NULL或在某些情况下使用不同的表达式,那么显然你必须使用扩展形式:

    CASE
       WHEN {expression} = {testvalue1} THEN {resultvalue1}
       WHEN {expression} = {testvalue2} THEN {resultvalue2}
       ...
    END
    

    但同样,这不应该影响你的情况。

    最后,如果您的表达式始终使用Max,请考虑进一步简化:

    MAX(
       CASE @detMethod
          WHEN 'MAX(cov)' THEN cov
          ELSE pcc * cov
       END
    )
    

    甚至(为了更好地向下一位开发者表达意图):

    MAX(
       cov *
          CASE @detMethod
             WHEN 'MAX(cov)' THEN 1
             ELSE pcc
          END
    )