isnumeric() incorrectly identifies numeric values in MSSQL
- I assumed that isnumeric() would tell me if the string was a number or not.
- How wrong I was, when I tried multiplying the number by 2, I got:
Msg 245, Level 16, State 1, Line 2 Conversion failed when converting the varchar value '$12.34' to data type int.
Applies to:
- Microsoft SQL Server 2000
- Microsoft SQL Server 2005
- Microsoft SQL Server 2008
Data used
- CREATE TABLE #temp (DATA VARCHAR(12));
- go
- INSERT INTO #temp VALUES('$12.34');
- INSERT INTO #temp VALUES('1.2e3');
- INSERT INTO #temp VALUES('12d3');
- INSERT INTO #temp VALUES('12.34');
- INSERT INTO #temp VALUES('1234');
- INSERT INTO #temp VALUES('-1234');
- INSERT INTO #temp VALUES('123,456,789');
- INSERT INTO #temp VALUES('123,4,56,789');
- INSERT INTO #temp VALUES('1234abcd');
- INSERT INTO #temp VALUES('abcd1234');
- INSERT INTO #temp VALUES(CHAR(9)); --tab
- INSERT INTO #temp VALUES(CHAR(32)); --space
- INSERT INTO #temp VALUES(CHAR(42)); --star
- go
- SELECT DATA FROM #temp;
- go
data ------------ $12.34 1.2e3 12d3 12.34 1234 -1234 123,456,789 123,4,56,789 1234abcd abcd1234 * (13 row(s) affected)
The last 3 items are:
- char(9) = a tab
- char(32) = a space
- char(42) = a star
isnumeric()
- isnumeric() falsely interpret non-numeric letters and symbols (such as D, E and $), and even tabs (char(9)) as numeric, when they are not.
- isnumeric() also gets confused with commas.
- SELECT DATA,
- ISNUMERIC(DATA) AS 'Result of isnumeric',
- CASE ISNUMERIC(SUBSTRING(DATA,1,1))
- WHEN 0 THEN '1st is: Character'
- WHEN 1 THEN '1st is: Numeric'
- END AS '1st char is:',
- CASE ISNUMERIC(DATA + 'e0')
- WHEN 0 THEN 'No'
- WHEN 1 THEN 'Yes'
- END AS 'Is really a number'
- FROM #temp
- go
data Result of isnumeric 1st char is: Is really a number
------------ ------------------- ----------------- ------------------
$12.34 1 1st is: Numeric No
1.2e3 1 1st is: Numeric No
12d3 1 1st is: Numeric No
12.34 1 1st is: Numeric Yes
1234 1 1st is: Numeric Yes
-1234 1 1st is: Numeric Yes
123,456,789 1 1st is: Numeric No
123,4,56,789 1 1st is: Numeric No
1234abcd 0 1st is: Numeric No
abcd1234 0 1st is: Character No
1 1st is: Numeric No
0 1st is: Character No
* 0 1st is: Character No
(13 row(s) affected)
Notice:
- The 1 in the column Result of isnumeric that is not lined up is because it's the char(9) or the tab character.
- Line 3: case isnumeric(substring(data,1,1)) returns numeric when it should not for:
- $
- -
- The way to really test if a value is numeric is to actually convert to the number power 0, meaning multiplying it by 1. So 12.34e0 is equal to 12.34 * 1 or 12.34
Note the following problems:
- Line 2: isnumeric('$12.34') returns true
- Line 3: isnumeric(substring('$12.34',1,1)) returns true which is wrong. substring('$12.34',1,1) is the $ and it's not a number.
- Line 7: isnumeric('$12.34' + 'e0') returns false because you are trying to multiply $12.34 by 1 and this fails.
When testing for numeric data do NOT use isnumeric() by itself but instead use isnumeric(data + 'e0')

