在 case 语句中转换 varchar 值时转换失败
Conversion failed when converting the varchar value in case statement
我无法理解它。我们有以下简单查询。
DECLARE @bFlag bit
SET @bFlag = 0
SELECT something = CASE
WHEN @bFlag = 1 THEN
CASE
WHEN RS.intInterval = 1 THEN '"Days"'
WHEN RS.intInterval = 2 THEN '"Weeks"'
WHEN RS.intInterval = 3 THEN '"Months"'
WHEN RS.intInterval = 4 THEN '"Years"'
END
Else
RS.intInterval
End
from MyTable AS RS WITH (NOLOCK)
所以如果flag
没有设置为true
,我想得到intInterval
(即int
)。否则,如果 flag
设置为 true
,我想根据 intInterval
的值获得 Days
、Weeks
等。如果我用 @bFalg = 1
运行 这个,我得到这个错误:
Conversion failed when converting the varchar value '"Weeks"' to data
type int
这没有任何意义,因为我没有转换任何东西。
我知道我可以通过将 cast (intInterval as varchar)
放在 else
部分来修复它。但是我想知道我收到此错误的原因,为什么 case
试图将 'Weeks' 转换为 int
?
使用CASE
语句时,所有结果表达式必须具有相同的数据类型。如果不是,则结果将转换为具有更高优先级的数据类型。根据 BOL:
Returns the highest precedence type from the set of types in
result_expressions and the optional else_result_expression.
由于 INT
的 data type precedence 高于 VARCHAR
,"Weeks"
被转换为 INT
并产生错误:
Conversion failed when converting the varchar value '"Weeks"' to data
type int
另一个会产生同样错误的例子:
SELECT CASE WHEN 1 = 1 THEN 'True' ELSE 0 END
解决方案是将RS.intInterval
转换为VARCHAR
:
CONVERT(VARCHAR(10), RS.intInterval)
您的最终查询应该是:
DECLARE @bFlag bit
SET @bFlag = 0
SELECT something = CASE
WHEN @bFlag = 1 THEN
CASE
WHEN RS.intInterval = 1 THEN '"Days"'
WHEN RS.intInterval = 2 THEN '"Weeks"'
WHEN RS.intInterval = 3 THEN '"Months"'
WHEN RS.intInterval = 4 THEN '"Years"'
END
Else
CONVERT(VARCHAR(10), RS.intInterval)
End
from MyTable AS RS WITH (NOLOCK)
我无法理解它。我们有以下简单查询。
DECLARE @bFlag bit
SET @bFlag = 0
SELECT something = CASE
WHEN @bFlag = 1 THEN
CASE
WHEN RS.intInterval = 1 THEN '"Days"'
WHEN RS.intInterval = 2 THEN '"Weeks"'
WHEN RS.intInterval = 3 THEN '"Months"'
WHEN RS.intInterval = 4 THEN '"Years"'
END
Else
RS.intInterval
End
from MyTable AS RS WITH (NOLOCK)
所以如果flag
没有设置为true
,我想得到intInterval
(即int
)。否则,如果 flag
设置为 true
,我想根据 intInterval
的值获得 Days
、Weeks
等。如果我用 @bFalg = 1
运行 这个,我得到这个错误:
Conversion failed when converting the varchar value '"Weeks"' to data type int
这没有任何意义,因为我没有转换任何东西。
我知道我可以通过将 cast (intInterval as varchar)
放在 else
部分来修复它。但是我想知道我收到此错误的原因,为什么 case
试图将 'Weeks' 转换为 int
?
使用CASE
语句时,所有结果表达式必须具有相同的数据类型。如果不是,则结果将转换为具有更高优先级的数据类型。根据 BOL:
Returns the highest precedence type from the set of types in result_expressions and the optional else_result_expression.
由于 INT
的 data type precedence 高于 VARCHAR
,"Weeks"
被转换为 INT
并产生错误:
Conversion failed when converting the varchar value '"Weeks"' to data type int
另一个会产生同样错误的例子:
SELECT CASE WHEN 1 = 1 THEN 'True' ELSE 0 END
解决方案是将RS.intInterval
转换为VARCHAR
:
CONVERT(VARCHAR(10), RS.intInterval)
您的最终查询应该是:
DECLARE @bFlag bit
SET @bFlag = 0
SELECT something = CASE
WHEN @bFlag = 1 THEN
CASE
WHEN RS.intInterval = 1 THEN '"Days"'
WHEN RS.intInterval = 2 THEN '"Weeks"'
WHEN RS.intInterval = 3 THEN '"Months"'
WHEN RS.intInterval = 4 THEN '"Years"'
END
Else
CONVERT(VARCHAR(10), RS.intInterval)
End
from MyTable AS RS WITH (NOLOCK)