So I just spent 5 hours troubleshooting a problem which turned out to be due not only to the old unreliable ISNUMERIC
but it looks like my problem only appears
For SQL Server 2005 and above.... take advantage of try/catch...
declare @test varchar(10), @num decimal
select @test = '0123A'
begin try
select @num = cast(@test as decimal)
print '1'
end try
begin catch
print '0'
end catch
prints 0.
Change @test = '01234' or @test = '01234.5' and it prints 1.
Another option might be to write an extended stored procedure in a language such as C, make it into a DLL and make it available to SQL Server.
I don't imagine it would take too many lines of code to do, and it probably would be faster than writing a Managed Stored Procedure in .NET, because you wouldn't incur the extra overheard from loading the CLR.
Here's a tidbit of information: http://msdn.microsoft.com/en-us/library/ms175200.aspx
Here's some C++ code that might work for you:
using namespace std;
int checkNumber() {
int number = 0;
cin >> number;
cin.ignore(numeric_limits<int>::max(), '\n');
if (!cin || cin.gcount() != 1)
cout << "Not a number.";
else
cout << "Your entered: " << number;
return 0;
}
Are you ever going to be handling number systems outside of your own (human) language, like Chinese etc? If so, I'd suggest using the libuninum library.
SQL 2012 onwards, you can use TRY_PARSE() function instead of ISNUMERIC().
SELECT
TRY_PARSE('123' as int) as '123'
,TRY_PARSE('abc' as int) as 'abc'
According to Microsoft support the only efficient way to replace UDF function is to write your own .NET function version.
Of course, if your database admin allows that :).
Mine doesn't :(.
IsNumeric() seems to have problems with spaces, 'D', 'E', dollar signs and all sorts of other characters. What we typically want is something that tells us whether a CAST or CONVERT will succeed. This UDF, while not the fastest solution, has worked very well for me.
create function dbo.udf_IsNumeric(@str varchar(50))
returns int
as
begin
declare @rtn int
select @rtn =
case
when ltrim(rtrim(@str)) in('.', '-', '-.', '+', '+.') then 0
when ltrim(rtrim(@str)) like '%[^-+.0-9]%' then 0
else isnumeric(@str)
end
return @rtn
end