在SQL Server 中,某列的数据都在int范围之内,但是使用sum聚集函数求该列和的时候,出现“将expression转化为数据类型int时发生算术溢出错误”。
问题在于定义的数据类型:
首先,我们先看看SQL Server 定义的数据类型的长度:
-
bigint 数据类型存储从 -2^63 (-9223372036854775808) 到 2^63-1 (9223372036854775807) 范围内的数字。存储大小为 8 个字节。
-
int 数据类型的存储范围是 -2,147,483,648 至 2,147,483,647(每个值需 4 个字节的存储空间)。
-
smallint 数据类型的存储范围只有 -32,768 至 32,767(每个值需 2 个字节的存储空间),tinyint 数据类型只能存储 0 至 255 范围内的数字(每个值需 1 个字节的存储空间)。
当我们对int类型的数据做sum操作的时候,就有可能发生算术溢出的问题。此时,我们可以采用在做sum操作前,将原有列的数据类型更改为bigint 。
S
QL 语句:
1. select sum(cast(colName as bigint)) from TableName
2. select sum(convert(numeric(20,0),colName)) from TableName
以上两种方法都是可以的。
在SQL Server 2005 中,我进行了测试:
使用方法1,虽然定义@c为bigint 类型,但是 仍然会出现“Arithmetic overflow error converting expression to data type int.” 错误。
通过方法2 和方法3 ,均可以得到最后结果为 3000000000
发现一个隐藏在项目里面的bug,项目一直都是正常的,突然某个月的月报出现问题,后来发现
时
select sum(test)这个函数sum里的数字越界了,利用cast进行类型转换即可
解决
问题,
select sum(cast(test as big
int
))......这样就没问题了。
有一个需求是要在一个云监控的状态值中
存储
多个状态(包括可同
时
存在的各种异常、警告状态)使用了位运算机制在一个
int
型中
存储
。
现在监控日志数据量非常大(亿级别)需要对数据按每小
时
、每天进行聚合,供在线报表使用。
状态分了3个级别:正常(0)、警告(1)、异常(2),聚合
时
需要使用max选择最差的状态,就需要对状态值进行处理加上级别和状态位个数,就要借助big
int
型来做运算了,
问题是再将big
int
转为
int
时
获取原始状态值
时
,
SQL
Server
报错了:
消息 8115,级别 16,状态 2,第 1 行
将
expression
转换为
数据类型
int
时
出现
算术溢出
错误
。
因为状态码中
在
SQL
Server
日常的函数、
存储
过程和
SQL
语句中,经常会用到不同
数据类型
的转换。在
SQL
Server
有两种数据转换类型:一种是显性数据转换;另一种是隐性数据转换。下面分别对这两种
数据类型
转换进行简要的说明:
1 显式转换
显示转换是将某种
数据类型
的表达式显式转换为另一种
数据类型
。常用的是CAST 和 CONVERT 函数。
CAST: CAST (
expression
AS data_type )
CONVERT: CONVERT (data_type[(length)],
expression
[, style])
参数
expression
是任何有效的 Microso
一、
Expression
2
Sql
介绍
Expression
2
Sql
是一个可以将
Expression
表达式树解析成Transact-
SQL
的项目。简单易用,几分钟即可上手使用,因为博主在设计
Expression
2
Sql
的
时
候就尽可能的按照Transact-
SQL
的语法语义风格来设计,只要调用者熟悉基本的Transact-
SQL
语法即可瞬间无忧开码,大大降低了学习
Expression
2
Sql
的成本,甚至...
当程序尝试
存储
对于声明的整数类型而言太大的整数值
时
,将
发生
整数溢出。这是一种
算术溢出
错误
,不仅会导致
错误
的结果和系统不稳定,还会导致缓冲区溢出,并为攻击者提供了切入点。让我们看看为什么可能
发生
整数溢出
错误
,它们怎么可能很危险,以及如何防止它们。为什么
发生
整数溢出在最基本的级别上,当算术运算的结果需要比目标变量更多的位
时
,将
发生
整数溢出。例如,您可以
存储
在32位无符号整数变量中的最大数字是...
我的 变量字段是
int
类型的
但是 统计过后的数据 超出了
Int
字段类型的 长度 ,所以报这个错了
解决
方案如下 把
int
类型转换成 big
int
类型 就可以 了
select sum(cast(
int
类型字段 as big
int
)) from 表
where 条件
这个问题是由于数据超大而引起的,那么当然要想办法把查询的
SQL
改下,考虑能不能将查询的数据
转化
下,
转化
程比
Int
类型
存储
范围大的
数据类型
。当然这只是个临
时
的
解决
方法,彻底
解决
这个问题还是要调整数据库将字段由
Int
型调整为适当类型。
在生产环境中遇到一个异常提示:“将
expression
转换为
数据类型
nvarchar
时
出现
算术溢出
错误
。”,一看这
错误
就知道是数据库的异常,赶紧检查
存储
过程。
发现
存储
过程中有将某个
int
值转换为nvarchar(2)的数据,心中一想,不会吧……这样也可以?万一
int
是自增的,过了100咋办?一查数据果然是此
int
类型值已达9800+,为确认是此处导致的问题,自己写个查询检查下: