当我尝试在下面的示例中设置变量@a时,有人可以为我澄清为什么会出现错误?
DECLARE @a BIGINT
SET @a = 7*11*13*17*19*23*29*31
/*
ERROR:
Msg 8115, Level 16, State 2, Line 1
Arithmetic overflow error converting expression to data type int.
*/
我现在能想到的是,在内部,SQL开始进行数学运算,评估乘法并将临时结果放入INT,然后将其转换为BIGINT。
但是,如果我在我的数字列表中添加 1.0 * ,则没有错误,因此我认为这次使用float作为临时结果,然后将其转换为BIGINT < / p>
DECLARE @b BIGINT
SET @b = 1.0 * 7*11*13*17*19*23*29*31
/*
NO ERROR
*/
坦率地说,我没有看到代码有什么问题......它很简单......
[我正在使用SQL 2008]
的 [编辑] 的
感谢Nathan link。 这是我不了解的好信息,但我仍然不明白为什么我会收到错误,为什么我要做“技巧”来获得这样一个简单的脚本。
作为程序员,我应该知道如何处理它?</ p>
或者,这是一个错误,如果是这样,我会考虑关闭这个问题。
答案 0 :(得分:9)
当你进行这样的计算时,个别数字的存储量足以容纳该数字,即:数字(1,0)。看看这个:
注意
当你使用+, - ,*时, /,或%算术运算符 执行隐式或显式 转换int,smallint,tinyint, 或者bigint常量值 浮点数,实数,十进制或数字数据 类型,SQL Server的规则 在计算数据时适用 表达式的类型和精度 结果取决于是否 查询是否自动参数化。因此,类似的表达方式 查询有时会产生 不同的结果。当查询不是 自动参数化,恒定值 首先转换为数字,其中 精度足以容纳 之前的常数的值 转换为指定的数据类型。 例如,常数值1是 转换为数字(1,0),和 常数值250被转换为 数字(3,0)。
当查询是自动参数化时, 常量值始终转换为 转换为之前的数字(10,0) 最终的数据类型。当。。。的时候 / 涉及运营商,不仅可以 结果类型的精度不同 类似的查询,但结果值 也可以有所不同。例如, 自动参数化的结果值 包含表达式的查询 SELECT CAST(1.0 / 7 AS float)会 与结果值不同 相同的查询不是 自动参数化,因为结果 自动参数化查询将是 截断以适应数字(10, 0)数据类型。欲获得更多信息 关于参数化查询,请参阅 简单的参数化。
http://msdn.microsoft.com/en-us/library/ms187745.aspx
这不是SQL Server中的错误。它从同一页面说明:
int数据类型是SQL Server中的主要整数数据类型。
和
SQL Server不会自动将其他整数数据类型(tinyint,smallint和int)提升为bigint。
这是定义的行为。作为程序员,如果您有理由相信您的数据会溢出数据类型,则需要采取预防措施来避免这种情况。在这种情况下,只需将其中一个数字转换为BIGINT
即可解决问题。
DECLARE @a BIGINT
SET @a = 7*11*13*17*19*23*29*CONVERT(BIGINT, 31)
答案 1 :(得分:5)
在第一个示例中,SQL Server将INT列表相乘,并发现结果太大而不能成为INT并生成错误。在第二个例子中,它注意到有一个浮点数,因此它首先将所有INT转换为浮点数,然后进行乘法运算。
同样,你可以这样做:
DECLARE @a BIGINT,
@b BIGINT
set @b = 1
SET @a = @b*7*11*13*17*19*23*29*31
这很好用,因为它注意到有一个BIGINT,所以它将所有INT转换为BIGINT,然后进行乘法。