|
|
|
Old Hand
      
Group: General Forum Members
Last Login: Thursday, May 09, 2013 11:53 AM
Points: 305,
Visits: 1,313
|
|
thanks ... its a good interview question
IMHO the only way this a good interview question is if the answer you're looking for is "I'm not sure of the correct answer because I would not rely on this implicit conversion. If I'm performing calculations I would explicitly cast / convert to the appropriate datatype."
Of course, I could just be bummed I got the question wrong
|
|
|
|
|
SSChasing Mays
      
Group: General Forum Members
Last Login: Today @ 5:38 AM
Points: 648,
Visits: 685
|
|
Hugo, your explanation is excellent, thank you. I wouldn't have thought it was any of those answers; my first guess was 112. I forgot about type precedence in the implicit conversion and simply read left to right, so I figured ' ' + @a would convert to ' 10' and then adding the 2 would result in ' 102'. So I've got type precedence pretty well hammered into my head now, thanks!
Of course that's the secondary lesson. The primary lesson is never to allow code like this in your database.
----- a haiku...
NULL is not zero NULL is not an empty string NULL is the unknown
|
|
|
|
|
SSCrazy
      
Group: General Forum Members
Last Login: Friday, May 17, 2013 11:53 AM
Points: 2,672,
Visits: 2,416
|
|
| Interesting question and follow up discussion. Hugo thanks for the additional explanation. I find it very interesting that ' ' is converted to a zero during a confused typing operation such as this.
|
|
|
|
|
SSC-Enthusiastic
      
Group: General Forum Members
Last Login: Thursday, July 22, 2010 8:59 AM
Points: 110,
Visits: 952
|
|
Good question for challenging what we know to be right with an edge case.
I second the opinion that code like this found in production warrants a red-card. Unfortunately we usually only find this stuff when whoever wrote it has left the company.
I also got this question wrong. I assumed it was a trick. Had I just done the obvious math I would have selected the correct answer.
|
|
|
|
|
SSCrazy
      
Group: General Forum Members
Last Login: Wednesday, May 15, 2013 3:05 PM
Points: 2,117,
Visits: 2,209
|
|
Great question. I got it wrong because I didn't know about the implicit conversion of string values containing only numbers.
For example, this code throws the error I expected:
declare @a int declare @b varchar(2)
set @a = 10 set @b = ' a'+@a + 2
select @a + @b
Messages: Server: Msg 245, Level 16, State 1, Line 5 Syntax error converting the varchar value ' a' to a column of data type int.
While answering the question, I thought only of those cases (probably the vast majority) where I had used code like the code above (for concatenation in printing test values only, not for adding numbers), and in variably it included at least one non-numeric character. So I was biased to think that such code would always throw an error.
This question is a nice corrective for my ignorance in that regard.
Thanks, webrunner
------------------- "The chemistry must be respected." - Walter White
"A SQL query walks into a bar and sees two tables. He walks up to them and says 'Can I join you?'" Ref.: http://tkyte.blogspot.com/2009/02/sql-joke.html
|
|
|
|
|
SSCommitted
      
Group: General Forum Members
Last Login: Thursday, May 16, 2013 12:39 PM
Points: 1,662,
Visits: 1,708
|
|
Thank you for an excellent explanation Hugo. The code like this should not be present anywhere near production of course, but the question is definitely a good one. One of the interesting side effects of implicit int to varchar conversions is that if the int value does not fit then varchar is set to *. For example, in the original example, if @a is set to 100 instead of 10 then it cannot fit into @b and this will cause @b = *, which can be somewhat confusing for someone who is unaware of this side effect. For example:
declare @a int; declare @b varchar(2);
set @a = 100; set @b = ' ' + @a + 2;
select @b; The result is
---- * This behavior is specific to int to varchar conversions only, other types such as smallint or bigint will cause the code to raise error.
Oleg
|
|
|
|
|
Hall of Fame
       
Group: General Forum Members
Last Login: Tuesday, May 14, 2013 4:11 PM
Points: 3,390,
Visits: 3,403
|
|
So given the following:
declare @a int declare @b varchar(2)
set @a = 10 set @b = ' ' IF ISNUMERIC(@b) = 1 select @b +@a + 2; ELSE Print 'Unknown'
-- Even though the following is the result select @b +@a + 2;
The result is 'Unknown' after which the actual result, 12.
|
|
|
|
|
Ten Centuries
      
Group: General Forum Members
Last Login: Friday, July 22, 2011 4:13 AM
Points: 1,149,
Visits: 603
|
|
As per Cliff Jones The answer should be 12 not 22 (I see I missed the Set followed by Select set @b = ' '+@a + 2 select @a + @b)
And as per Oleg Netchaev With SSMS 2008 I got an * but not with SSMS 2005
|
|
|
|
|
UDP Broadcaster
      
Group: General Forum Members
Last Login: Wednesday, April 17, 2013 10:57 PM
Points: 1,491,
Visits: 3,008
|
|
Hugo Kornelis (3/25/2010)
Good question, but unfortunately the explanation is not entirely correct. Especially this part is very misleading: Also the preceding space is not considered while performing the operation. . . . . Order of precedence dictates conversion of varchar to int, and ' ' is converted to the value 0 . . . . Thanks for the detailed explanation, Hugo. You beat me to it in pointing out that spaces (or an empty string) cast to numeric as value zero. A slight twist on the QOD code would dramatically illustrate that the leading spaces are not at all ignored:
declare @a int declare @b varchar(2) set @a = 10 set @b = ' '+@a + 2 select @a + @b as Original set @b = ' '*@a + 2 --Multiply instead select @a + @b as Revised
Results are:
Original ----------- 22
(1 row(s) affected)
Revised ----------- 12
(1 row(s) affected)
|
|
|
|
|
SSCoach
         
Group: General Forum Members
Last Login: Today @ 7:19 AM
Points: 18,733,
Visits: 12,331
|
|
john.arnott (3/25/2010)
Hugo Kornelis (3/25/2010)
Good question, but unfortunately the explanation is not entirely correct. Especially this part is very misleading: Also the preceding space is not considered while performing the operation. . . . . Order of precedence dictates conversion of varchar to int, and ' ' is converted to the value 0 . . . . Thanks for the detailed explanation, Hugo. You beat me to it in pointing out that spaces (or an empty string) cast to numeric as value zero. A slight twist on the QOD code would dramatically illustrate that the leading spaces are not at all ignored: declare @a int declare @b varchar(2) set @a = 10 set @b = ' '+@a + 2 select @a + @b as Original set @b = ' '*@a + 2 --Multiply instead select @a + @b as Revised
Results are: Original ----------- 22
(1 row(s) affected)
Revised ----------- 12
(1 row(s) affected)
Another fine explanation of the conversion.
Jason AKA CirqueDeSQLeil I have given a name to my pain... MCM SQL Server 2008
SQL RNNR
Posting Performance Based Questions - Gail Shaw Posting Data Etiquette - Jeff Moden Hidden RBAR - Jeff Moden VLFs and the Tran Log - Kimberly Tripp
|
|
|
|