我正在使用带有包含varchar的列的视图,该varchar可以具有类似8.60
或V
或NULL
的值。
我正在尝试创建一个select语句,该语句在可能的情况下将值转换为数字,否则返回原始值。
所以我想到了这个测试查询:
SELECT
CASE
WHEN ISNUMERIC('V') = 1
THEN cast(round('V', 1) as numeric(4,1))
ELSE 'V'
END
as Value;
我希望它返回V
,但出现错误:Error converting data type varchar to numeric.
我尝试使用TRY_PARSE
和TRY_CAST
以及round
和cast
都没有成功。错误似乎与THEN
子句有关,因为如果没有,它不会引发错误。
我应该如何编写此查询?
SQL版本: Microsoft SQL Server 2014(SP2-GDR)(KB4019093)-12.0.5207.0(X64)
使用:Microsoft SQL Server Management Studio v12.0.2000.8
答案 0 :(得分:6)
一个case
表达式返回一个值。该值具有单一类型。您的case
表达式同时返回一个数字和一个字符串。数字优先,因此SQL Server尝试将字符串转换为数字。
因此,您的错误。
您可以通过取消使用'V'
并仅使用NULL
来解决此问题:
SELECT (CASE WHEN ISNUMERIC('V') = 1
THEN cast(round('V', 1) as numeric(4,1))
ELSE NULL
END) as Value;
或更简单地说:
SELECT TRY_CONVERT(numeric(4, 1), 'V')
注意:我假设您打算将'V'
作为示例字符串值而不是作为列。如果是一列,单引号就是错误的。
答案 1 :(得分:2)
案例表达式不能返回多种数据类型。 SQL Server必须将结果从所有分支转换为一种数据类型。并且根据数据类型优先级规则,numeric
的优先级高于varchar
,因此它将v
转换为数字。您可以将数值转换为varchar。
话虽如此,我不鼓励使用ISNUMERIC
,因为对于诸如$
和-
之类的废话,它返回true。按照其他答案中的建议使用TRY_CAST
:
SELECT CASE
WHEN TRY_CAST(v AS NUMERIC(4, 1)) IS NOT NULL THEN
CAST(CAST(v AS NUMERIC(4, 1)) AS VARCHAR(100)) -- cast will round as well
ELSE v
END