在where子句中使用decimal - 将nvarchar转换为数据类型numeric的算术溢出错误

时间:2014-12-02 12:02:22

标签: sql sql-server

我收到了一个sql server错误,不确定如何修复它。我有一个专栏' NAME'在一个视图'产品'类型为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)) 

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

非常感谢!

1 个答案:

答案 0 :(得分:2)

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。联机丛书在DECIMALNUMERIC的数据类型定义中说明:

  

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

因此,当您使用常量'12 .0'发出查询时,它将转换为数据类型NUMERIC(3,1),然后尝试将NVARCHAR值转换为匹配。