我正在尝试动态地将一列添加到我的查询中。
我正在运行以下查询:
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。它给我的错误行号是派生表的第一行。
答案 0 :(得分:2)
我看到两种可能性:
cov
和pcc
的数据类型为varchar
,并且包含无法转换为float
的值; 将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
)