字段为数字时强制转换为数字

时间:2018-11-09 12:17:58

标签: sql sql-server numbers sql-server-2014

我正在使用带有包含varchar的列的视图,该varchar可以具有类似8.60VNULL的值。

我正在尝试创建一个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_PARSETRY_CAST以及roundcast都没有成功。错误似乎与THEN子句有关,因为如果没有,它不会引发错误。

我应该如何编写此查询?

SQL版本: Microsoft SQL Server 2014(SP2-GDR)(KB4019093)-12.0.5207.0(X64)

使用:Microsoft SQL Server Management Studio v12.0.2000.8

2 个答案:

答案 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