【问题标题】:Arithmetic overflow error converting varchar to data type numeric. '10' <= 9.00将 varchar 转换为数字数据类型的算术溢出错误。 '10' <= 9.00
【发布时间】:2012-10-31 15:20:21
【问题描述】:

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

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”是否

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。

谢谢。

【问题讨论】:

  • 算术溢出错误,你确定?不是conversion error
  • 尝试在转换中显式CAST(val AS DECIMAL(9,2)) &lt;= CAST(9.00 AS DECIMAL(9,2)) 给了什么?
  • GSerg - 是的,将 varchar 转换为数字的算术溢出。 Dems - 这确实有效!但是,我想了解为什么隐式转换不起作用?我的想法是它可以进行这种转换并且不应该引起问题?
  • 无论如何,这都不是一种安全的查询方式。见SQL Server should not raise illogical errors。尽管使用了子查询,演员仍然可能被推下并针对值 Yes 发生。

标签: sql sql-server-2008 tsql


【解决方案1】:

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

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

解决方案当然是使用显式转换而不是隐式进行

【讨论】:

  • 我还注意到,假设您有一个Decimal (5,3),而您拥有的号码是12.321,它将被接受。但是如果你的号码是123.321 6 digits in total 所以不会接受它。你的小数点应该是Decimal (6,3)。这只是我测试并证实了自己SQL 2014
  • @Pierre 是的,这实际上只是 DECIMAL 数据类型规范的定义。
【解决方案2】:

来自BOL

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

这意味着您的常量9.00 将具有精度为 1 和刻度为 0 精度为 3 和刻度为 2,因此它不能存储值 10,这需要2 + scale 的最小精度。

您需要用CASTCONVERT 包裹IntsOnly.Val 以指定正确的精度和小数位数。

【讨论】:

  • 我确定你的意思是写 2 的比例?
  • 这取决于SQL引擎有多聪明;它可以转换为numeric(3, 2),因为小数点后有两位数,也可以转换为numeric(1, 0),因为小数点后的数字都是0
  • 它查看小数点右侧的所有零,但忽略左侧的所有前导零。所以00000.0000numeric(4,4)
【解决方案3】:

试试这个...它对我有用

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多