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

    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

    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
    InstapaperVote on HN

    8 comments

    Comment from: Jerry Hung [Visitor] · http://www.SQLServerNewbie.com
    Jerry Hung 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)
    12/05/08 @ 08:09
    Comment from: SQLDenis [Member] Email
    *****
    SQLDenis Jerry,

    gmmastros has the same link in the blogpost itself, right before the first block of code
    12/05/08 @ 10:03
    Comment from: George Mastros (gmmastros) [Member]
    George Mastros (gmmastros) 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.
    12/05/08 @ 10:08
    Comment from: SQL Smarty [Visitor]
    *----
    SQL Smarty 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.
    12/08/08 @ 07:50
    Comment from: Ted Krueger (onpnt) [Member]
    *****
    Ted Krueger (onpnt) 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
    12/08/08 @ 08:42
    Comment from: Christiaan Baes (chrissie1) [Member]
    Christiaan Baes (chrissie1) Anonymous comments are never taken seriously.
    12/08/08 @ 11:13
    Comment from: Naomi Nosonovsky [Member]
    Naomi Nosonovsky Excellent post.
    11/06/09 @ 07:12
    Comment from: Hoang [Visitor]
    Hoang thank a lot!
    11/07/10 @ 23:45

    Leave a comment


    Your email address will not be revealed on this site.

    To mislead the spambots.

    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.)