SQL Server timestamp转datetime遇算术溢出错误(Msg 8115)求解决建议
解决SQL Server中
CONVERT(datetime, timestamp)的算术溢出错误 问题根源
首先得明确一个关键概念:SQL Server里的timestamp(现在官方更推荐叫rowversion)根本不是用来存储日期时间的!它是个自动生成的8字节二进制值,唯一作用就是跟踪表中行的修改顺序,和实际时间半毛钱关系都没有。
你执行CONVERT(datetime, D.TimeStamp)时触发Msg 8115溢出错误,核心原因是:这个二进制值被SQL Server当作整数处理后,对应的时间远远超出了datetime类型的范围(datetime仅支持1753-01-01到9999-12-31)。咱们算一下你的值:
SELECT CAST(0x000000000D8B2E9E AS BIGINT) -- 结果是 227306142
如果把这个数当成天数加到1900-01-01上,得到的是距今几百万年的时间,完全超出了datetime的上限,不溢出才怪!
可行的解决办法
1. 换用专门的日期字段(最推荐)
如果你的目的是记录行的修改时间,那从一开始就不该用timestamp。赶紧给表加个日期时间字段,比如:
ALTER TABLE YourTableName ADD LastModified DATETIME2 DEFAULT GETDATE()
要是需要自动更新这个字段,可以写个触发器,或者在应用更新数据的时候同步修改它,这样就能直接拿到准确的时间,根本不用折腾转换。
2. 明确转换规则(仅当你确定二进制值对应有效时间)
如果你这个二进制值确实是某种时间戳(比如其他系统传过来的Unix时间戳),得先搞清楚它的含义。比如如果是从1970-01-01开始的秒数,这么转:
SELECT DATEADD(SECOND, CAST(0x000000000D8B2E9E AS BIGINT), '1970-01-01')
注意:datetime不支持1970年之前的时间,要是需要更早的时间,换成datetime2类型更稳妥。
3. 别再打rowversion的时间主意了
记住,rowversion的唯一使命就是标记行是否被修改,它不存储任何时间信息。想要时间,必须单独存。
内容的提问来源于stack exchange,提问作者syed mohsin
相关产品推荐
相关产品推荐

