获取将varchar转换为float的错误.
有一个表(不是我的制作)与列结果,有varchar数据.我想转换为float以获取所有值> 180.0.
SELECT result FROM table WHERE result > 180.0
产生错误.有趣的是,尽管如此:
WITH temp AS ( CASE WHEN ISNUMERIC(result)=1 THEN CAST(result as FLOAT) ELSE CAST(-1.0 AS FLOAT) END AS result )
这很好.当我配对时:
SELECT temp.result FROM temp WHERE temp.result > 180.0
我再次收到错误.思考?
更新:完整代码请求…
WITH temp AS ( SELECT CASE WHEN ISNUMERIC(result)=1 THEN CAST(result as FLOAT) ELSE CAST(-1.0 AS FLOAT) END AS result FROM table) SELECT temp.result FROM temp WHERE temp.result > 180.0
使用sql-SERVER 2008 RC2.
解决方法
这意味着表中至少有一行无法转换为float.执行CASE是安全的,但是在编写T-sql时,将CTE和添加WHERE子句组合在一起会成为程序员的常见谬误:声明顺序意味着执行顺序.程序员习惯于C语言的命令式程序风格,并且无法理解sql的基于声明集的本质.我之前写过关于这个问题的文章,并在谬误导致错误时举例说明:
> T-SQL functions do no imply a certain order of execution
> On SQL Server boolean operator short-circuit
一旦发布完整的代码,我们就可以看到你在哪种情况下确实在你的情况下做出了谬误并假定了一定的执行顺序.
更新后
好的,所以我必须管理你的情况下代码在执行顺序是正确的,结果列不能在没有首先评估CASE的情况下进行预测.如果CASE在WHERE子句中,那么事情会有所不同.
你的问题是不同的:ISNUMERIC
.这个函数非常慷慨地理解了NUMERIC的含义并且之前已经咬过很多开发人员.也就是说,它接受CAST和CONVERT拒绝的值.就像包含逗号的那些:
declare @n varchar(8000) = '1,000'; select isnumeric(@n); select cast(@n as float); select case when isnumeric(@n)=1 then cast(@n as float) else null end;
因此,您拥有通过ISNUMERIC测试但未能转换的值.只是一个抬头,你越是深入研究这种方法,你会发现越多的门.只是没有安全的方法来进行服务器端所需的转换.理想情况下,修复数据模型(如果存储浮点数,则使该字段为浮点数).除此之外,对数据进行分类并删除所有不正确的浮点值,并修复前端/应用程序不再引入新的值,然后添加一个约束,如果出现新的错误值,将触发错误.你将无法在一个查询中解决这个问题,那条路上到处都是尸体.
使用下一版本的sql Server,您将拥有一个可以解决问题的新功能TRY_CONVERT
.