SQL Server 2008 R2:varchar类型'10'与float 1.1比较时算术溢出错误
嘿,这个问题我碰到过不少次,尤其是在SQL Server 2008 R2这种没有TRY_CAST/TRY_CONVERT的老版本里,给你几个实用的解决办法:
1. 先搞清楚溢出的根源
你说'10'转float都触发溢出?大概率不是'10'本身的问题,要么是你的varchar列里藏了非打印字符(比如空格、制表符),要么是SQL Server在隐式转换时的优先级问题——比如你直接写WHERE YourVarcharCol > 1.1,SQL会尝试把整个列转成float,只要有一行值超出float范围,就会导致全表报错。
2. 自定义函数安全检查可转换性
因为2008 R2没有TRY系列函数,我们自己写个标量函数,用TRY/CATCH捕获转换错误(包括溢出):
CREATE FUNCTION dbo.IsValidFloat(@input VARCHAR(MAX)) RETURNS BIT AS BEGIN DECLARE @result BIT = 0 BEGIN TRY -- 先清理前后空格,再尝试转换 DECLARE @dummy FLOAT = CAST(LTRIM(RTRIM(@input)) AS FLOAT) SET @result = 1 END TRY BEGIN CATCH -- 转换失败(溢出、非数值都算)就返回0 SET @result = 0 END CATCH RETURN @result END
3. 改造你的代理作业更新逻辑
用上面的函数判断哪些行无法转换为float,然后标记INRLevelYN:
UPDATE YourTableName SET INRLevelYN = 1 WHERE dbo.IsValidFloat(YourVarcharColumn) = 0
这样就不会因为转换溢出导致整个作业失败了。
4. 安全比较数值的方法
如果要和1.1这种float值比较,先过滤出能安全转换的行,再做转换比较:
SELECT * FROM YourTableName WHERE dbo.IsValidFloat(YourVarcharColumn) = 1 AND CAST(LTRIM(RTRIM(YourVarcharColumn)) AS FLOAT) > 1.1
这样只有能成功转换的行才会进入比较逻辑,不会触发溢出错误。
额外排查点
如果确实是'10'这种值也报错,建议检查列里的实际内容,看看有没有非打印字符:
SELECT YourVarcharColumn, ASCII(LEFT(YourVarcharColumn, 1)) AS FirstCharASCII, ASCII(RIGHT(YourVarcharColumn, 1)) AS LastCharASCII FROM YourTableName WHERE YourVarcharColumn LIKE '%10%'
如果发现有特殊字符,用REPLACE或者LTRIM/RTRIM清理掉即可。
内容的提问来源于stack exchange,提问作者SteveB
相关产品推荐
相关产品推荐

