Sql 无法将值强制转换为浮点值

Sql 无法将值强制转换为浮点值,sql,sql-server-2008,Sql,Sql Server 2008,我们有一个SQL,它在ColumnA上执行强制转换函数(浮动)。SQL有一个过滤器,它最终将间接过滤掉ColumnA中具有非数值的行。然而,由于我认为是由于并行运行SQL的某些部分,我认为转换甚至应用于过滤掉的行,这导致SQL在“无法将值转换为浮点…”时失败 我知道如果我通过添加查询提示以一个进程运行 OPTION (MAXDOP 1) SQL是否按预期运行。我怀疑在1 proc上运行会强制应用过滤器以清除columnA中具有非数值的行,从而成功转换其值。我还发现使用查询提示 OPTION (

我们有一个SQL,它在ColumnA上执行强制转换函数(浮动)。SQL有一个过滤器,它最终将间接过滤掉ColumnA中具有非数值的行。然而,由于我认为是由于并行运行SQL的某些部分,我认为转换甚至应用于过滤掉的行,这导致SQL在“无法将值转换为浮点…”时失败

我知道如果我通过添加查询提示以一个进程运行

OPTION (MAXDOP 1)
SQL是否按预期运行。我怀疑在1 proc上运行会强制应用过滤器以清除columnA中具有非数值的行,从而成功转换其值。我还发现使用查询提示

OPTION (FORCE ORDER)
修复了这个问题,我假设是因为这也确保了首先应用过滤器,并且我获得了比在一个圆柱体上运行的过滤器更好的查询性能

我倾向于使用第二个选项解决问题。如果我对这里发生的事情有任何误解,或者有人想阐述我的一般理解或提出建议,我将不胜感激

我在跑步

Microsoft SQL Server 2008 R2(RTM)-10.50.1720.0(X64)2010年6月12日 01:34:59版权所有(c)微软公司企业版 Windows NT 5.2上的(64位)(内部版本3790:Service Pack 2)

事后思考:

如果T-SQL有以下函数来检查字符串是否可以转换为特定的数据类型,那就太好了

IsFloat 数字的 伊森特格 等


我真的很恼火,我在数据库中找到了很多列定义为varchar(255)的各种数据。我想解决办法是“不要那样做!”

关于你的事后想法

如果T-SQL具有以下功能,那就太好了 检查字符串是否可以转换为特定的数据类型

SQL Server 2012确实引入了这一需求。因此,下面的查询将返回
NULL
,而不是错误

SELECT TRY_CONVERT ( FLOAT, 'Fish')
即使使用系列计划,也不能保证在评估
SELECT
之前会出现
WHERE
子句。正如从SQLServer2005开始所解释的,与以前的版本相比,这种情况更可能发生。具体的做法如下

SQL Server 2005有时在查询中计算表达式的速度比 在SQL Server 2000中对其进行评估时。此行为提供了 以下是重要的好处:

  • 将计算列上的索引与查询中与计算列表达式相同的表达式相匹配的能力
  • 防止表达式结果的冗余计算
克雷格·弗里德曼(Craig Freedman)的另一篇好博客文章中有更多关于这种行为的讨论

在2012年之前的版本和
TRY_CONVERT
上,您需要将
强制转换为FLOAT
封装在
CASE
语句中。e、 g

  SELECT CASE WHEN ISNUMERIC(Col)=1 THEN CAST(Col AS FLOAT) END AS Col
  FROM Table
  WHERE ISNUMERIC(Col)=1
这仍然不能绝对保证防止出现错误,因为
ISNUMERIC
本身只是检查该值是否会转换为一种数值数据类型,而不是专门转换为浮点值

案例
在在线书籍中被记录为大部分短路()


您还可以在连接项和SQLKiwi的a中找到关于此问题的其他讨论/投诉,我相信您是正确的。CONVERT()函数是在谓词“间接过滤”行之前应用的

为了避免这种异常,您是正确的,一种方法是尝试对执行计划中的操作顺序获得一定程度的控制。如果语句提示对您有效,那么您可以使用它。(就我个人而言,暗示是我最后的选择。)

请注意,SQL Server确实有一个IsNumeric函数

IsNumeric函数有些不足,因为有些值将“通过”IsNumeric测试,但在转换为数字数据类型时会引发异常

就我个人而言,我倾向于采用这种方法:

select convert(float,case when isnumeric( t.foo )=1 then t.foo else null end)
而不是语句级提示

或者,我将指定其他谓词,它们将“过滤”掉不应转换的值

select convert(float,case when t.fi in ('fo','fum') then t.foo else null end)

你让我们帮你修车,却没有看到你的车。请给我们看看这辆车。@Dems-而且它非常不可靠:)浮点数有问题,我会避免使用这种数据类型,并使用十进制、整数、货币或其他。正确的解决方案确实是修复潜在的设计问题。@mark-
FLOAT
有它的位置。建议某人不要使用数据类型是相当愚蠢的,因为“存在问题”