求助:将varchar转换为numeric时出现算术溢出错误
解决「Arithmetic overflow error converting varchar to data type numeric」报错问题
嘿,我来帮你搞定这个SQL转换溢出的问题!你遇到的这个错误,本质是**hours字段里的某些字符串值,要么超出了numeric(18,2)的存储范围,要么本身包含无法正常转换为数字的内容**——毕竟hours是varchar类型,很容易混入各种不规范的值。
第一步:先找出搞事情的异常数据
要解决问题,得先定位到底哪些hours值在搞鬼,你可以跑下面这个查询:
SELECT [hours] FROM [dbo].[KSFTABLE] WHERE [hours] IS NOT NULL AND [hours] NOT IN (' ', '-') -- 先筛掉明显不是数字的 AND ISNUMERIC([hours]) = 0 UNION ALL -- 再筛掉能识别为数字但超出numeric(18,2)范围的 SELECT [hours] FROM [dbo].[KSFTABLE] WHERE [hours] IS NOT NULL AND [hours] NOT IN (' ', '-') AND ISNUMERIC([hours]) = 1 AND (CAST([hours] AS FLOAT) > 9999999999999999.99 OR CAST([hours] AS FLOAT) < -9999999999999999.99);
注意:ISNUMERIC可能会把带$、,这类符号的字符串判定为数字,如果你hours里有这类格式,还得额外加个替换逻辑,比如REPLACE(REPLACE([hours], ',', ''), '$', '')。
第二步:优化你的UPDATE语句
根据你的SQL版本,有两种靠谱的解决方式:
方案1:用TRY_CAST(SQL Server 2012及以上版本适用)
TRY_CAST是个神器——它在转换失败时会返回NULL,不会直接抛出错误,完全适配你的需求,还能简化你的CASE判断:
UPDATE [dbo].[KSFTABLE] SET [BIGCLEAN] = TRY_CAST([hours] AS NUMERIC(18,2));
解释一下:不管hours是NULL、空串、'-'还是转换失败的异常值,TRY_CAST都会返回NULL,刚好符合你原来CASE语句的逻辑。
方案2:适配老版本SQL Server(不支持TRY_CAST)
如果你的SQL Server版本比较老,那就先做范围过滤,再转换:
UPDATE [dbo].[KSFTABLE] SET [BIGCLEAN] = CASE WHEN [hours] IS NULL OR [hours] IN (' ', '-') THEN NULL -- 先判断数值是否在numeric(18,2)的范围内(最大值9999999999999999.99,最小值-9999999999999999.99) WHEN CAST([hours] AS FLOAT) BETWEEN -9999999999999999.99 AND 9999999999999999.99 THEN CAST([hours] AS NUMERIC(18,2)) ELSE NULL -- 超出范围的也设为NULL,避免触发溢出错误 END;
额外小建议
- 长远来看,建议把
hours字段的类型改成numeric(18,2)——既然它要存的是数值,直接用数值类型从根源上避免转换问题。 - 检查一下
hours的数据源,为什么会出现超出范围的数值?从源头规范数据录入,能省掉很多后续的麻烦。
内容的提问来源于stack exchange,提问作者Karen Fireman
相关产品推荐
相关产品推荐

