将varchar转换为数据类型numeric的算术溢出错误。 '10'< = 9.00

时间:2012-10-31 15:20:21

标签: sql sql-server-2008 tsql

下面是我正在使用的表结构和数据类型的子集。

CREATE TABLE #Test
(
     Val varchar(5)
    ,Type varchar(5)
)

INSERT #Test VALUES ('Yes','Text')
INSERT #Test VALUES ('10','Int')
INSERT #Test VALUES ('10.00','Float')
INSERT #Test VALUES ('9.00','Float')
INSERT #Test VALUES ('9','Int')

我想编写一个查询,让我知道列'Val'是< = 9.00(必须是数字数据类型)。我通过以下方式做到了这一点:

SELECT *
FROM
    (
        SELECT Val
        FROM #Test
        WHERE Type = 'Int'
    ) IntsOnly
WHERE IntsOnly.Val <= 9.00

这给了我一个算术溢出错误。但是,如果我使用值“10”排除数据行:

SELECT *
FROM
    (
        SELECT Val
        FROM #Test
        WHERE Type = 'Int'
        AND Val <> '10'
    ) IntsOnly
WHERE IntsOnly.Val <= 9.00

它没有任何问题。 我的问题不是如何解决这个问题,因为我知道我可以简单地将数据转换为我需要的格式。

我的问题是为什么'Val'列中'10'的值返回错误。当然逻辑应该只返回'False'并简单地排除行,因为'10'(我假设是隐式转换的)大于9.00。

感谢。

3 个答案:

答案 0 :(得分:13)

这会产生算术溢出,因为它试图隐式地将Val列转换为NUMERIC(3,2),这自然会溢出2位数值,如10。

它使用NUMERIC(3,2)作为目标类型和大小,因为这是9.00似乎适合的最小数字。

当然,解决方案是使用explict CASTing而不是隐式执行

答案 1 :(得分:4)

来自BOL

  

在Transact-SQL语句中,具有小数点的常量将使用所需的最小精度和小数位自动转换为数字数据值。例如,常量12.345将转换为精度为5且比例为3的数值。

这意味着你的常量9.00的精度为1,精度为0 ,精度为3,刻度为2,因此无法存储值{{1} },需要最小精度为10

您需要使用2 + scaleIntsOnly.Val包裹CAST以指定正确的精度和比例。

答案 2 :(得分:-1)

尝试这个...对我有用

     CAST(CAST(@UR_VARIABLE AS FLOAT) AS NUMERIC(3,2))