Search code examples
sql-server-2008isnumeric

IsNumeric in SQL Server JOIN


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!!


Solution

  • You can't count on the order in which a database will evaluate filtering expressions. There is a query optimizer that will evaluate your SQL and build a plan to execute the query based on what it perceives will yield the best performance.

    In this context, IsNumeric() cannot be used with an index, and it means running a function against every row in the table. Therefore, it will almost never provide the best perceived performance. Compare this with the SrcID > 15 expression, which can be matched with an index (if one exists), and is just a single operator expression even if one doesn't. It can also be used to filter down the number of potential rows where the IsNumeric() function needs to run.

    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