Login or Sign Up to become a member!
LessThanDot Sit Logo

LessThanDot

Data Management

Less Than Dot is a community of passionate IT professionals and enthusiasts dedicated to sharing technical knowledge, experience, and assistance. Inside you will find reference materials, interesting technical discussions, and expert tips and commentary. Once you register for an account you will have immediate access to the forums and all past articles and commentaries.

LTD Social Sitings

Lessthandot twitter Lessthandot Linkedin Lessthandot friendfeed Lessthandot facebook Lessthandot rss

Note: Watch for social icons on posts by your favorite authors to follow their postings on these and other social sites.

Your profile

Authors

Search

XML Feeds

Google Ads

« SQL Friday, The Best SQL Server Links Of The Past Week Episode 1sqltrace: A Tool Every SQL Server Developer Should Have »
comments
Rate Post:
submit to reddit Digg!FacebookDotnetkicks

When you write a case/when statement in T-SQL, it's critically important that you cause all return values to have the same data type. If you don't do this, you open yourself up to conversion problems. This problem can occur even if some branches of the code are never executed.

When SQL Server compiles the code, it analyzes all branches of execution and determines the return data type. It does not matter that your particular query does not use a particular branch of execution. If it's there, it will be considered.

This article describes data type precedence that sql server uses:
http://msdn.microsoft.com/en-us/library/ms190309.aspx

Here is some code that highlights this issue:

  1. DECLARE @DATA VARCHAR(20)
  2.  
  3. SET @DATA = ''
  4.  
  5. SELECT CASE WHEN @DATA IS NULL THEN NULL
  6.             WHEN @DATA = ''    THEN 'Data is empty'
  7.             WHEN 0=1           THEN 1
  8.             END

Since @Data = '', the code should return 'Data is empty'. In this case, it doesn't because the 0=1 branch causes SQL Server to 'attempt' to convert each return value to an integer, and fails.

When mixing numbers and strings, SQL Server prefers (based on data type precedence) to convert data to numbers. This is a little unfortunately because all number data can be converted to a string, but not all strings can be converted to a number.

The fix for this particular problem is to convert everything to a string. Basically, if you want even just one branch of a Case/When statement to return a string, then you should make sure all branches return a string.

  1. DECLARE @DATA VARCHAR(20)
  2.  
  3. SET @DATA = ''
  4.  
  5. SELECT CASE WHEN @DATA IS NULL THEN NULL
  6.             WHEN @DATA = ''    THEN 'Data is empty'
  7.             WHEN 0=1           THEN CONVERT(VARCHAR(10), 1)
  8.             END

Now, each branch returns a string (or NULL, which doesn't matter), so there will not be any problems with running this code.

About the Author

George has been developing software professionally for 19 years, first for the department of defense, and then for various other companies. In 1998, George started his software company, Orbit Software, specializing in School Bus Transportation software. His specialty is refining SQL Server queries to deliver optimal performance.
Social SitingsTwitterLTD RSS Feed
4000 views
submit to reddit Digg!FacebookDotnetkicks

Comments and Feedback

7 comments

Comment from: Jerry Hung [Visitor] · http://www.SQLServerNewbie.com
The reason Numbers (int...) comes before String (varchar etc) is because of Data Type Precedence
http://msdn.microsoft.com/en-us/library/ms190309.aspx

Normally the CASE statement will return similar/exact data types (all strings, all numbers, etc...)

A lazier way/trick is
WHEN 0=1 THEN STR(1)
05/12/08 @ 08:09
Comment from: SQLDenis [Member] Email
*****
Jerry,

gmmastros has the same link in the blogpost itself, right before the first block of code
05/12/08 @ 10:03
Comment from: George Mastros [Member] Email
Another trick could have been:

WHEN 0=1 Then '1'

I chose to put the convert code in there because real world code may not be using hard coded literals, but may actually have a column there instead. I wanted to emphasize that a conversion to a string was important to ensure a consistent data type for the return value.
05/12/08 @ 10:08
Comment from: SQL Smarty [Visitor]
*----
I thought you learned this at the SQL 101 class...if you just found this out and are actually in a developer role, you need to request a "Beginner" training course from your manager.
08/12/08 @ 07:50
Comment from: onpnt [Member] Email
*****
blogs serve several different purposes. The main two are to write articles on what you think is benefiting to the community as a new or old concept they should know and also to write about things you simply have just learned and want to pass along.

If you read anything on gmmastros's history and web presence I think you'd know you just made yourself look like the one needing 101 educational classes
08/12/08 @ 08:42
Comment from: chrissie1 [Member] Email
Anonymous comments are never taken seriously.
08/12/08 @ 11:13
Comment from: Naomi [Member] Email
Excellent post.
06/11/09 @ 07:12

Leave a comment


Your email address will not be revealed on this site.

Your URL will be displayed.
(Line breaks become <br />)
(Name, email & website)
(Allow users to contact you through a message form (your email will not be revealed.)