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

JBo*_*ond 9 sql t-sql sql-server-2008

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

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')
Run Code Online (Sandbox Code Playgroud)

我想写一个查询,让我知道列'Val'是否<= 9.00(必须是数字数据类型).我通过执行以下操作来完成此操作:

SELECT *
FROM
    (
        SELECT Val
        FROM #Test
        WHERE Type = 'Int'
    ) IntsOnly
WHERE IntsOnly.Val <= 9.00
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

谢谢.

RBa*_*ung 16

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

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

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

  • 我还注意到,可以说您有一个“十进制(5,3)”,而您拥有的数字是“ 12.321”,这将被接受。但是,如果您的电话号码是123.321 &lt;-,则总计为6位数,因此我们不会接受。然后,您的小数应为“小数(6,3)”。这只是我已经测试并确认自己是“ SQL 2014”的内容 (2认同)
  • @Pierre是的,这就是`DECIMAL`数据类型规范的定义. (2认同)