解决 SQL Server 数据类型异常的问题
微软的产品总是非常的神奇,能让你在不经意间发现一些意料之外的事情。我一直觉得使用微软的产品有两个好处,除了它的通用性,另一点就是可以丰富我们的想象力。可见这个公司存在的必然性,除了平时给我们带来一些跨行业的新闻(即娱乐行业新闻),还有助于我们的自身建设。
今天就为了“将 expression 转换为数据类型 int 时发生算术溢出错误”这个问题折腾了一会。
下午的时候,发现我所维护的一个系统中数据存在异常,我直接联想到 SQL 代理可能又挂掉了。连上企业管理器发现它好好的活着,只是几个调度中的某几个存在异常,上次状态是失败:
查看了作业历史记录,看到日志如下:
从系统事件中找到日志记录,其事件 ID 是 17177。奇怪的是在微软知识库中无法找到相关文章:
无奈之下,重新找到这个数据库调度的执行脚本,一个存储过程:
DECLARE @all BIGINT
令人匪夷所思的地方就在这里了,@all 变量已经声明为 BIGINT 了,难道还不够?我把 SQL 查询直接扔到查询分析器中跑了一下,结果是这样的:
SELECT @all = SUM(object_a) + SUM(object_b) + SUM(object_c)
FROM table_name
WHERE some_condition = 'some value'
将 expression 转换为数据类型 int 时发生算术溢出错误
我猜测可能 SQL 在执行过程中由于某些未知的原因,依旧使用 INT 在做计算;因而在 SUM a 或者 b 或者 c 的时候已经大于 22 亿,超过了 INT 的承受范围,于是报错。
看样子光声明变量的类型还不够,干脆强制到 BIGINT 算了:
DECLARE @all BIGINT
嗯,现在终于很好、很和谐了。有关 CAST 的说明,请参阅 SQL Server 联机丛书的相关页面。
SELECT @all = SUM(CAST(place_a AS BIGINT)) + SUM(CAST(place_b AS BIGINT)) + SUM(CAST(place_c AS BIGINT))
FROM table_name
WHERE some_condition = 'some value'
和谐地终于又出问题了
这样只能解决SUM(object_a) + SUM(object_b) + SUM(object_c)表达式中三个数加总大于INT的问题,而单个表达式比如object_a本身进行了SUM时就超过INT还是会发生问题。所以在这里应该使用CAST对object_a进行修饰,而不是SUM的结果:
SUM(CAST(place_a AS BIGINT)) + SUM(CAST(place_b) AS BIGINT) + SUM(CAST(place_c AS BIGINT))
感谢和谐的Henry Xu,问题已得到和谐的解决.