SQL Server JOIN中的IsNumeric

时间:2012-01-17 14:54:25

标签: sql-server-2008 isnumeric

我的问题似乎很简单,但我被困在这里。我有一个表有一个名为“SrcID”的“nvarchar”列,我存储了数字和字符串。现在,当我尝试在“加入”条件下检查该列上的“IsNumeric”时,如下所示,

   ISNUMERIC(SrcID) = 1 AND SrcID > 15

我收到以下错误:

  Msg 245, Level 16, State 1, Line 47
  Conversion failed when converting the nvarchar value 'Test' to data type int.

令人惊讶的是,当我删除支票“SrcID> 15”时,我的查询运行正常。我应该在此声明中包含其他内容吗?

请帮我解决问题。在此先感谢!!

2 个答案:

答案 0 :(得分:3)

您不能指望数据库评估过滤表达式的顺序。有一个查询优化器将评估您的查询并根据最佳性能构建执行查询的计划。表达式SrcID > 15可以与索引匹配,但IsNumeric(SrcID) = 1 不能与索引匹配,因此可能首先评估SrcID > 15,因为它有助于更快地过滤掉更多潜在记录。

您可以使用视图,子查询,CTE,CASE语句或计算列来解决此问题。这是一个CTE示例:

With NumericOnly As 
(
    SELECT <columns> FROM MyTable WHERE IsNumeric(SrcID) = 1
)
SELECT <columns> FROM NumericOnly WHERE SrcID > 15

这是一个CASE语句选项:

SELECT <columns> FROM MyTable WHERE CASE WHEN IsNumeric(SrcIC) = 1 THEN Cast(SrcID As Int) ELSE 0 END > 15

答案 1 :(得分:2)

WHERE子句中的过滤器不会按任何特定顺序进行评估。

这是对SQL Server的常见误解 - 优化程序将检查它认为最快/最简单的条件,并尽可能以最有效的方式限制数据。

在您的示例中,您可能在SrcID上有一个索引,并且优化器认为将FIRST限制为SrcID > 15的位置会更快,然后在所有这些行上运行该函数(因为该函数需要检查每一行,否则)。

您可以尝试使用括号强制执行操作顺序,例如:

WHERE (ISNUMERIC(SrcID) = 1) AND SrcID > 15

或者使用案例陈述:

WHERE CASE WHEN ISNUMERIC(SrcID) = 1 THEN SrcID > 15 ELSE 1=0 END