IsNumeric in SQL Server JOIN

ぃ、小莉子 提交于 2019-12-10 20:48:54

问题


My problem seems to be very simple but I'm stuck here. I have a table which has an "nvarchar" column called "SrcID" and I store both numbers and strings in that. Now, when I try to check for "IsNumeric" on that column in a "Join" condition, something like below,

   ISNUMERIC(SrcID) = 1 AND SrcID > 15

I am getting the following error:

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

Amazingly, when I remove the check "SrcID > 15", my query is running properly. Should I include anything else in this statement?

Please help me in fixing the issue. Thanks in advance!!


回答1:


You can't count on the order in which a database will evaluate filtering expressions. There is a query optimizer that will evaluate your query and build a plan to execute your query based on best performance. The expression SrcID > 15 can be matched with an index, but IsNumeric(SrcID) = 1 cannot be matched with an index, and so SrcID > 15 is likely to be evaluated first, because it helps filter out more of the potential records more quickly.

You can likely get around this with a view, a subquery, a CTE, a CASE statement, or a computed column. Here's a CTE example:

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

And here's a CASE statement option:

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



回答2:


The filters in a WHERE clause are not evaluated in any particular order.

This is a common misconception with SQL Server - the optimizer will check whichever conditions it thinks it can the fastest/easiest, and try to limit the data in the most efficient way possible.

In your example, you probably have an index on SrcID, and the optimizer thinks it will be quicker to FIRST limit the results to where the SrcID > 15, then run the function on all those rows (since the function will need to check every single row otherwise).

You can try to force an order of operations with parentheses like:

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

Or with a case statement:

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



来源:https://stackoverflow.com/questions/8896728/isnumeric-in-sql-server-join

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!