问题
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