views:

341

answers:

7

Hi everyone.

I'm selecting a value out of a table that can either be an integer or a nvarchar. It's stored as nvarchar. I want to conditionally call a function that will convert this value if it is an integer (that is, if it can be converted into an integer), otherwise I want to select the nvarchar with no conversion.

This is hitting a SQL Server 2005 database.

select case
    when T.Value (is integer) then SomeConversionFunction(T.Value)
    else T.Value
end as SomeAlias

from SomeTable T

Note that it is the "(is integer)" part that I'm having trouble with. Thanks in advance.

UPDATE

Check the comment on Ian's answer. It explains the why and the what a little better. Thanks to everyone for their thoughts.

+2  A: 

You can't have a column that is sometimes an integer and sometimes a string. Return the string and check it using int.TryParse() in the client code.

erikkallen
There is no client code here. This directly feeds SSRS.
Joe Behymer
SSRS uses vb.net for custom functions. This is client code
gbn
+2  A: 

ISNUMERIC. However, this accepts +, - and decimals so more work is needed.

However, you can't have the columns as both datatypes in one go: you'll need 2 columns.

I'd suggest that you deal with this in your client or use an ISNUMERIC replacement

gbn
sql_variant allows for different types including nvarchar and int.
Dead account
+1  A: 

IsNumeric will get you part of the way there. You can then add some further code to check whether it is an integer

for example:

select top 10 
    case 
        when isnumeric(mycolumn) = 1 then 
            case 
                when convert(int, mycolumn) = mycolumn then
                    'integer'
                else
                    'number but not an integer'
            end
        else 
            'not a number'
    end 
from mytable
Chris Simpson
This only tells you the type: not the actual values which can't happen because a column has exactly one datatype
gbn
I don't believe that this will work. When it attempts the CONVERT(INT, mycolumn) it will cause an error if the column is actually a decimal.
Tom H.
gbn: this was just example code, you could substitute the text values I have written for the actual value itself (and whatever values you want the defaults to be). Tom H: converting a float to int will not cause an error, it will just truncate the decimal bits
Chris Simpson
+3  A: 
 select case
     when ISNUMERIC(T.Value) then T.Value 
     else SomeConversionFunction(T.Value)
 end as SomeAlias

Also, have you considered using the sql_variant data type?

Dead account
ISNUMERIC does not workIf it did: This can't happen because a column has exactly one datatype
gbn
http://msdn.microsoft.com/en-us/library/ms173829.aspx -- "A data type that stores values of various SQL Server-supported data types"
Dead account
Ian hit it on the head. I don't need to store two different data types. Rather, I'm only interested if the number CAN BE CONVERTED. This is all about what I want to display, and how I display it. If its an int, it needs converted to its cooresponding value. If its a string, I just display that.
Joe Behymer
Also, thanks for the tip about the sql_variant. I'll definitely look into that. Cheers!
Joe Behymer
So use vb.net in your report
gbn
Why use VB when I can do it in SQL? By that logic, why don't I just create a service in the cloud which I can call to check whether or not it can be parsed into an integer? That way I'm using a whole handful of technologies that aren't needed.
Joe Behymer
+1  A: 

To clarify some other answers, your SQL statement can't return different data types in one column (it looks like the other answers are saying you can't store different data types in one column - yours are all strign represenations).

Therefore, if you use ISNUMERIC or another function, the value will be cast as a string in the table that is returned anyway if there are other strigns being selected.

If you are selecting only one value then it could return a string or a number, however your front end code will need to be able to return the different data types.

ck
+2  A: 

The result set can only have one type associated with it for each column, you will get an error if the first row converts to an integer and there are strings that follow:

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

try this to see:

create table  testing
(
strangevalue   nvarchar(10)
)

insert into testing values (1)
insert into testing values ('word')
select * from  testing

select
    case
        when ISNUMERIC(strangevalue)=1 THEN CONVERT(int,strangevalue)
        ELSE strangevalue
     END
FROM testing

best bet is to return two columns:

select
    case
        when ISNUMERIC(strangevalue)=1 THEN CONVERT(int,strangevalue)
        ELSE NULL
     END AS StrangvalueINT
    ,case
        when ISNUMERIC(strangevalue)=1 THEN NULL
        ELSE strangevalue
     END AS StrangvalueString
FROM testing

or your application can test for numeric and do your special processing.

KM
A: 

Just to add to some of the other comments about not being able to return different data types in the same column... Database columns should know what datatype they are holding. If they don't then that should be a BIG red flag that you have a design problem somewhere, which almost guarantees future headaches (like this one).

Tom H.