我在做一个SELECT
,它使用CASE
到nvarchar的值转换成合适的类型,像这样:
SELECT CASE
WHEN @propType = 'money' THEN convert(money, datavalue)
[...]
ELSE datavalue
END
FROM [...]
然而,似乎在convert
总是执行,即使@propType
不等于金钱。 可运行的例子:
declare @proptype nvarchar(50)= 'nvarchar'
declare @val nvarchar(10) = 'test'
select
case @proptype
when 'money' then convert(money, @val)
else @val
end
这是为什么,我怎么能围绕它得到什么? MSDN文档这样说:
CASE语句计算条件的顺序和第一条件,其条件得到满足将停止。 在一些情况下,CASE语句接收表达作为其输入的结果之前表达式。 在评估这些表述错误是可能的。 出现在当争吵到CASE语句首先计算聚合表达式,然后提供给CASE语句。 例如,以下查询零错误产生MAX聚合的值时产生分频。 这发生之前评估CASE表达式。
我不知道这是相关的,但语言是有点重了非本地的,所以也许它是什么?
看一看下面用CASE或IF中的Transact SQL(T-SQL)函数使用CONVERT()时要小心
第一个想法通常是一个下面的“自评估的第一个值是数字,将其转换为十进制,和所有其他数据预计将是一个小数,以及” OR“如果SQL Server能够转换的任何值为指定的类型,则所有值预计是经转换的类型”的。 然而,这不是正确的(虽然第二接近)!
真正的问题是,如果你选择在Case语句中的任何位置转换的值,该数据类型要转换的值是所有值的预期类型,不管它们是该类型与否。 此外,即使值都不能真正转化(即使代码转换线从未执行),所有值仍有望被转换函数指定的类型!
要清楚发生了什么then
子句不正在评估。
你看到了同样的错误,如果你做
SELECT CASE @proptype
WHEN 'money' THEN $1.0 /*<-- Literal of datatype money*/
ELSE @val
END
对于文档CASE
解释说,返回类型
返回从类型集合最高的优先级类型result_expressions
和可选else_result_expression
。 欲了解更多信息,请参阅数据类型优先级(Transact-SQL) 。
money
具有更高的数据类型优先级比nvarchar
所以else @val
评价那么被转换为money
和失败。
一个可能的解决办法是将它转换到sql_variant
,因为这比都较高的数据的优先级。
declare @proptype nvarchar(50)= 'nvarchar'
declare @val nvarchar(10) = 'test'
select
case @proptype
when 'money' then convert(money, @val)
else cast(@val as SQL_VARIANT)
end