views:

524

answers:

3

I have a nvarchar column BigMacs in table McTable in my MS SQL 2005 database with alfanumeric and numeric values. For example:

  • 132
  • 432adfad
  • sfs54543
  • 5256

And now i would like to do something like this:

select Convert(BigMacs, int) from McTable
where IsNumerc(BigMacs) = 1 AND Convert(BigMacs, int) > 6

But when I do this i get a error:

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

On line select.

How to fix this?

+2  A: 

Try this:

SELECT  *
FROM    (
        SELECT  REPLACE(BigMacs, ',', '.') AS BigMacs
        FROM    McTable m
        WHERE   IsNumerc(BigMacs) = 1
        ) q
WHERE   CAST(BigMacs AS DECIMAL) > 6

IsNumeric will return TRUE on decimal fractions like 1234.1232, but they cannot be converted to INT.

Checking:

WITH McTable AS
        (
        SELECT '123124,123123' AS BigMacs
        )
SELECT  *
FROM    (
        SELECT  REPLACE(BigMacs, ',', '.') AS BigMacs
        FROM    McTable
        WHERE   IsNumeric(BigMacs) = 1
        ) q
WHERE   CAST(BigMacs AS DECIMAL) > 6

-----------
123124.123123
Quassnoi
This is not working (condition in select?). And when I move it to where i get error: Error converting data type nvarchar to numeric., but when I get select IsNumeric(BigMacs) I get all 1.
tomaszs
What exactly are you trying to SELECT? What does this '> 6' condition mean? Are you trying to select all applicable rows and find out if they are greater than 6, or to filter out those rows less than 6?
Quassnoi
I would like to get rows from McTable that have numeric value in BigMacs and that this value is greater than 6
tomaszs
See updated post
Quassnoi
Now i get Error converting data type nvarchar to numeric. on Select * from first line.
tomaszs
I'm sorry but this solution will not work. See my post for an explanation
edosoft
But what is the solution ?
tomaszs
This seems to be locale dependent. You'll need to replace a comma with a period. See updated post.
Quassnoi
Yes, but I dont have any period and any dot in my column.
tomaszs
My point is that IsNumeric() returns 1 for values that cannot be cast to a decimal. You cannot rely on it.
edosoft
Could you please locate the rows that fails? Try adding TOP N to your query, increasing N, and locate that very row that fails.
Quassnoi
I've tried it. And it came out that the value is 44 and it occurs 3 times in this column.
tomaszs
Could it please post CAST(BigMacs AS BINARY) for this row?
Quassnoi
I've did it, and value is : 0x340034000000000000000000000000000000000000000000000000000000
tomaszs
Google found a hack: Use isnumeric(BigMac + 'e0'). See my edited answer
edosoft
You are right Edoode, thank you!
tomaszs
+1  A: 

This is probably because the IsNumeric function returns true for any value that COULD be converted to a number. Try the following example:

create table McTable  (BigMac varchar(255))

insert into McTable  select '1p927'
insert into McTable  select '1927'
insert into McTable  select '1,927'
insert into McTable  select '1.927'

select BigMac, isnumeric(BigMac)
from McTable 

select BigMac, CAST(BigMac AS DECIMAL)
from McTable 
where isnumeric(BigMac) = 1

Even though all rows except the '1p927' are numeric, the cast will fail! This is because '1,927' cannot be converted to a Decimal (on my machine)

IsNumeric doesn't work exactly as specified. As found here, you could use

IsNumeric (data + 'e0')

-Edo

edosoft
Ok, but when I select from select still I get this error (like Spencer Ruport)
tomaszs
I don't have coma or dot in my values.
tomaszs
My point is that IsNumeric() returns 1 for values that cannot be cast to a decimal. You cannot rely on it.
edosoft
I've added this function and did this:select * from(select BigMac, CAST(BigMac AS DECIMAL) ValueSfrom McTablewhere dbo.isReallyNumeric (BigMac) = 1) tableeWHERE tablee.ValueS > 5But still I get:Error converting data type nvarchar to numeric.
tomaszs
@tomaszs: you have some weird values in your table :)
edosoft
You saved my day Edoode!
tomaszs
+2  A: 

There are many ways to accomplish this. Both of these work the same. It is best not to use replace in this situation as there are too many unknowns to account for to replace. It is best to filter everything that is NOT what your after.

SELECT
    CONVERT(INT,BigMacs) AS BigMacs
FROM
    McTable
WHERE
    ISNUMERIC(BigMacs) = 1
AND PATINDEX('%[^0-9]%', BigMacs) = 0


SELECT
    CONVERT(INT,BigMacs) AS BigMacs
FROM
    McTable
WHERE
    ISNUMERIC(BigMacs) = 1
AND BigMacs NOT LIKE ('%[^0-9]%')

Note: It helps if people spell ISNUMERIC() correctly. It also helps if you use the correct syntax order on CONVERT()

DBAndrew