0

Hi I have a stored procedure which suppose to compare between 2 columns on different tables

  1. Users.ID => int
  2. Trans.ID => nvarchar

Sometimes the value in Trans.ID is not numeric at all, and sometimes it's null, which causes an error while trying to compare

is there a way to try to parse Trans.ID into a number and in case it doesn't succeed to return 0??

I tried NullIf() but it doesn't work when the value inside is not numeric.

rs.
  • 26,707
  • 12
  • 68
  • 90
user1326293
  • 923
  • 2
  • 9
  • 24

5 Answers5

3

Assuming Trans.ID is a varchar(20) field, you can convert the Users.ID field to a varchar, use COALESCE to handle NULL values, and compare as follows:

WHERE CAST(Users.ID AS varchar(20)) = COALESCE(Trans.ID, '')
LittleBobbyTables - Au Revoir
  • 32,008
  • 25
  • 109
  • 114
3

If using sql server you can do this

CASE WHEN ISNUMERIC(Trans.ID) = 0  then null 
else cast(Trans.ID as int) end = Users.ID
rs.
  • 26,707
  • 12
  • 68
  • 90
1

you can do something like:

select * from users u 
inner join trans t on u.userid  = (CASE WHEN ISNUMERIC(t.id) = 1 THEN CONVERT(int, t.id) ELSE 0 END)

hope this helps.

Losbear
  • 3,255
  • 1
  • 32
  • 28
0

If it is just equality comparison (which I think it is to make sense), I would convert Users.ID to NVARCHAR and then compare with Trans.ID.

Vikdor
  • 23,934
  • 10
  • 61
  • 84
0

IsNumeric() is not always right, e.g. ' - ' and '.' both return 1 for IsNumeric, but will fail your query.

This function (Adapted from here)

create function dbo.GetNumeric(@x varchar(10)) returns float as
begin
return
    case
    when @x is null or @x = '' then null -- blanks
    when @x like '%[^0-9e.+-]%' then null -- non valid char found
    when @x like 'e%' or @x like '%e%[e.]%' then null -- e cannot be first, and cannot be followed by e/.
    when @x like '%e%_%[+-]%' then null -- nothing must come between e and +/-
    when @x='.' or @x like '%.%.%' then null -- no more than one decimal, and not the decimal alone
    when @x like '%[^e][+-]%' then null -- no more than one of either +/-, and it must be at the start
    when @x like '%[+-]%[+-]%' and not @x like '%[+-]%e[+-]%' then null
    else convert(float,@x)
    end
end

Your query (involving inequality)

where users.id >= case when IsNull(dbo.GetNumeric(trans.id),0)

And if trans.id does not involve decimal points

where user.id >= case when trans.id not like '%[^0-9]%' and trans.id >''
                      then trans.id end

Of course, if it's a simple equality, just cast the int to a varchar

where right(users.id,10) = trans.id
Community
  • 1
  • 1
RichardTheKiwi
  • 105,798
  • 26
  • 196
  • 262