【问题标题】:using decimal in where clause - Arithmetic overflow error converting nvarchar to data type numeric在 where 子句中使用小数 - 将 nvarchar 转换为数据类型 numeric 的算术溢出错误
【发布时间】:2014-12-02 12:02:21
【问题描述】:

我遇到了一个 sql server 错误,不知道如何修复它。我在视图“产品”中获得了一个类型为 nvarchar(30) 的列“名称”,查询是在代码中动态生成的,因此无法完全改变它.

我收到“将 nvarchar 转换为数字数据类型的算术溢出错误”。对于以下查询:

select * FROM Products WHERE  NAME=12.0

但是以下查询可以正常工作:

select * FROM Products WHERE  NAME=112.0

我对这个错误感到很困惑,我知道我应该在数字周围加上引号,但只想知道为什么第二个查询有效,是否有任何设置可以使第一个查询有效?

更新:也

select * FROM Products WHERE  NAME=cast('12.0' as decimal(4,2))

没用,但是

select * FROM Products WHERE  NAME=cast('12.0' as decimal(5,2)) 

有效,有什么特别的原因吗?

非常感谢!

【问题讨论】:

  • 如果NAMEvarchar(),则将其与varchar() 进行比较,而不是数字:NAME = '12.0'
  • @GordonLinoff,是的,这行得通,但为什么 112.0 可以正常工作,而 12.0 不行?
  • 没有设置和所有。在您的动态查询句柄中使用 CAST 或 CONVERT 函数。 select * FROM #temp WHERE col1=cast (12.0 as nvarchar(30)) .....正如 Gordon 所说的 EQUAL to operator excepts 数据类型在符号的两侧应该相同。

标签: sql sql-server


【解决方案1】:

SQL Server 正在尝试转换表中的值以匹配编码到 WHERE 子句中的值的感知数据类型。如果您的数据值具有更多数字(例如,DECIMAL(5,2))并且您尝试将它们转换为匹配具有更少数字的值(例如,DECIMAL(3,1)),那么您将发生溢出。

考虑以下 SQL,它将引发错误:

DECLARE @Products TABLE (NAME NVARCHAR(30))
INSERT INTO @Products VALUES ('123.45')
INSERT INTO @Products VALUES ('12.0')

SELECT *
FROM @Products
WHERE NAME = 12.0

现在试试这个,它会起作用:

DECLARE @Products TABLE (NAME NVARCHAR(30))
INSERT INTO @Products VALUES ('123.45')
INSERT INTO @Products VALUES ('12.0')

SELECT *
FROM @Products
WHERE NAME = CAST(12.0 AS DECIMAL(5,2))

它们之间的区别在于,SQL Server 现在考虑了表包含的数字的精度和/或比例比 WHERE 子句中指定的数字更高的情况。

编辑:further reading。 Books Online 在DECIMALNUMERIC 的数据类型定义中指出:

在 Transact-SQL 语句中,带小数点的常量是 使用最小值自动转换为数值数据值 精度和规模是必要的。例如,常数 12.345 是 转换为精度为 5、小数位数为 3 的数值。

因此,当您使用常量“12.0”发出查询时,它会被转换为数据类型NUMERIC(3,1),然后尝试转换NVARCHAR 值以匹配。

【讨论】:

  • 感谢 Ahiggins,这解释了很多,表中最大的数字是 500,所以 112.0 有效,在我将 1000 放入表中后,112.0 失败。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-05-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多