【发布时间】:2016-07-05 07:40:18
【问题描述】:
有人能解释一下为什么SELECT的整数乘法会失败吗?
SELECT 1024*1024*1024*1024 -- ERROR
是不是乘法结果大于INT数据类型阈值?
DECLARE @VAL AS BIGINT
SET @VAL = 1024 -- OK
SET @VAL = 1024*1024 -- OK
SET @VAL = 1024*1024*1024 -- OK
SET @VAL = 1024*1024*1024*1024 -- ERROR
SET @VAL = 1099511627776 -- OK - 1024*1024*1024*1024=1099511627776
SET @VAL = CAST((1024*1024*1024*1024) AS BIGINT) -- ERROR
错误信息
将表达式转换为数据类型 int 时出现算术溢出错误。
int, bigint, smallint, and tinyint (Transact-SQL)
注意
当您使用 +、-、*、/ 或 % 算术运算符将 int、smallint、tinyint 或 bigint 常量值隐式或显式转换为 float、real、decimal 或 numeric 数据类型时,规则SQL Server 在计算表达式结果的数据类型和精度时应用的内容取决于查询是否自动参数化。
因此,查询中的相似表达式有时会产生不同的结果。当查询未自动参数化时,在转换为指定的数据类型之前,首先将常量值转换为精度刚好足以容纳常量值的数值。例如,常量值 1 转换为数值 (1, 0),常量值 250 转换为数值 (3, 0)。
当查询被自动参数化时,常量值总是在转换为最终数据类型之前转换为数字 (10, 0)。当涉及 / 运算符时,不仅结果类型的精度在相似查询之间会有所不同,而且结果值也会有所不同。例如,包含表达式 SELECT CAST (1.0 / 7 AS float) 的自动参数化查询的结果值将不同于未自动参数化的同一查询的结果值,因为自动参数化查询的结果将被截断以适应转化为数字 (10, 0) 数据类型。
【问题讨论】:
-
是的,这就是算术溢出,内存不足来存储结果。
-
错误消息似乎很明显 - “将表达式转换为数据类型 int 的算术溢出错误。”推测一个int是32位的,1024^4 == (2^10)^4 == 2^40 超出了32位Integer (2^32)的范围
-
SELECT CAST(1024 AS BIGINT) * 1024 * 1024 *1024 -
试试
select SQL_VARIANT_PROPERTY(CONVERT(sql_variant,1099511627776),'BaseType')看看为什么你的select 1099511627776有效,但不是你想象的那样。 -
谢谢 Damien,但为什么 select SQL_VARIANT_PROPERTY(CONVERT(sql_variant,1024*1024*1024*1024.0),'BaseType') 返回数字而不是浮点数?
标签: sql-server