Log in  ::  Register  ::  Not logged in

 Recent PostsRecent Posts Popular TopicsPopular Topics
 Home Search Members Calendar Who's On

 Extracting a Numeric Reference from a VARCHAR field Rate Topic Display Mode Topic Options
Author
 Message
 Posted Wednesday, November 19, 2008 8:16 PM
 SSC-Addicted Group: General Forum Members Last Login: Tuesday, November 26, 2013 3:56 PM Points: 477, Visits: 396
 Comments posted to this topic are about the item Extracting a Numeric Reference from a VARCHAR field
Post #605532
 Posted Thursday, November 20, 2008 6:46 AM
 SSCrazy Group: General Forum Members Last Login: 2 days ago @ 8:27 AM Points: 2,556, Visits: 746
 declare @myTab table( ExtRef varchar(9), IntRef decimal(38,19))insert into @myTab(ExtRef,IntRef) values ('1',0)insert into @myTab(ExtRef,IntRef) values ('2.1',0)insert into @myTab(ExtRef,IntRef) values ('A',0)update @myTabset IntRef = case when isnumeric(ExtRef) = 1 then ExtRef else -1 --(A) endupdate @myTabset IntRef = case when isnumeric(ExtRef) = 1 then ExtRef else -1 --(A) endConfused here --(A) is a comment, yes?The cast to decimal would be required otherwise a failure converting varchar to decimal. Jamie
Post #605765
 Posted Thursday, November 20, 2008 6:51 AM
 SSCommitted Group: General Forum Members Last Login: Wednesday, October 02, 2013 11:19 AM Points: 1,816, Visits: 399
 I'm using SQL Server 2008.To get the script to work for decimal numbers like 35.12, I had to changewhen isnumeric(ExtRef) = 1 then ExtRefto when isnumeric(ExtRef) = 1 then cast(ExtRef as decimal)After I made that change, I was able find the problem that decimal data with dollar signs are considered numeric but can't be cast as decimals.Jim
Post #605770
 Posted Thursday, November 20, 2008 6:54 AM
 SSCrazy Group: General Forum Members Last Login: 2 days ago @ 8:27 AM Points: 2,556, Visits: 746
 Jim,Out of the box SQL 2005declare @myTab table( ExtRef varchar(9), IntRef decimal(38,19))insert into @myTab(ExtRef,IntRef) values ('\$1.00',0)insert into @myTab(ExtRef,IntRef) values ('2.1',0)insert into @myTab(ExtRef,IntRef) values ('A',0)update @myTabset IntRef = case when isnumeric(ExtRef) = 1 then cast(ExtRef as decimal(38,19))else cast(-1 as decimal(38,19)) --(A) endGood catch on the dollar sign! Jamie
Post #605772
 Posted Thursday, November 20, 2008 7:19 AM
 Ten Centuries Group: General Forum Members Last Login: Friday, December 06, 2013 2:52 PM Points: 1,168, Visits: 1,932
 Additionally,1. It doesn't properly support a legitimate value of -1 as -1 is being used to indicate that the value is not numeric.2. An explicit CAST is needed in the assignment part ("THEN") of the CASE statement as for some quirky reason, a value of '123.45' cannot be implicitly converted to DECIMAL(38,19) when it is part of a CASE statement. Error: Conversion failed when converting the varchar value '123.45' to data type int. Yet a direct assignment (IntRef = ExtRef) works fine! (SQL Server 2005 SP2) (PHB) I think we should build an SQL database. (Dilbert) What color do you want that database? (PHB) I think mauve has the most RAM.
Post #605787
 Posted Thursday, November 20, 2008 7:35 AM
 Grasshopper Group: General Forum Members Last Login: Wednesday, November 20, 2013 2:06 PM Points: 20, Visits: 188
 I see the exact same behavior with 2000.
Post #605813
 Posted Thursday, November 20, 2008 7:40 AM
 Hall of Fame Group: General Forum Members Last Login: Monday, December 02, 2013 9:48 AM Points: 3,357, Visits: 674
 JohnG -If you cast the -1 to Decimal(38,19), you won't get the error on 123.45Great question.
Post #605820
 Posted Thursday, November 20, 2008 10:09 AM
 SSC Eights! Group: General Forum Members Last Login: Sunday, November 17, 2013 10:31 PM Points: 942, Visits: 1,047
 I liked the question; I didn't think about it when I answered it much (so I got it wrong ). The SQL syntax looked right, but needed to read it a bit more carefully I guess.I just got confused by -- (A); I wasn't sure what was being implied by that when I read the options available to me. ---Mohit K. Gupta, MCITP: Database Administrator (2005), My Blog, Twitter: @SQLCAN.Microsoft FTE - SQL Server PFE * Some time its the search that counts, not the finding...* I didn't think so, but if I was wrong, I was wrong. I'd rather do something, and make a mistake than be frightened and be doing nothing. How to ask for help .. Read Best Practices here.
Post #605965
 Posted Thursday, November 20, 2008 12:50 PM
 UDP Broadcaster Group: General Forum Members Last Login: Monday, November 11, 2013 6:35 AM Points: 1,435, Visits: 2,073
 Good one! Jason ShadonixMCTS, SQL 2005
Post #606062
 Posted Monday, November 24, 2008 1:33 AM
 SSCertifiable Group: General Forum Members Last Login: Yesterday @ 2:09 PM Points: 5,600, Visits: 7,799
 JohnG (11/20/2008)Additionally,1. It doesn't properly support a legitimate value of -1 as -1 is being used to indicate that the value is not numeric.2. An explicit CAST is needed in the assignment part ("THEN") of the CASE statement as for some quirky reason, a value of '123.45' cannot be implicitly converted to DECIMAL(38,19) when it is part of a CASE statement. Error: Conversion failed when converting the varchar value '123.45' to data type int. Yet a direct assignment (IntRef = ExtRef) works fine! (SQL Server 2005 SP2)Hi John,Well, your first point is by design. If the design calls for -1 being used to represent incorrect format, you can't blame the code for using -1 for two purposes. Apparently, the assumption here is that -1 will never be a real value in the data. :)WRT the second point - the reason is not "quirky" at all. The data type of the CASE is always equal to a data type used in one of the WHEN clauses or the ELSE clause, with the choice being determined by the rules of precedence. In the posted code, data types used were varchar(9) (from the ExtRef column) and int (from the constant -1, as a constant with no decimal point and within the range of integers is always considered to be int). Of these, int has the highest precedence, so the varchar is converted. And after that, the result of the CASE is converted to decimal(38,19) for the purpose of assiging it to the IntRef column.I'll gladly admit that I missed this double conversion myself. Fortunately I did not lose a point over it as I am well aware of the limitations of ISNUMERIC(), but it wasn't until I read the comments here that I noticed the code would choke on "really" valid decimal numbers as well due to the hidden conversion to integer.Good question! Hugo Kornelis, SQL Server MVPVisit my SQL Server blog: http://sqlblog.com/blogs/hugo_kornelis
Post #607355

 Permissions