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

    « Virtual Lab: Creating the Basic SQL 2008 R2 Virtual Machine12 ways to break your database server before the first transaction »
    comments

    I have a bunch of processes that run at then end of the day. Some of these processes are configured dynamic since table names, server names, database names and a whole bunch of other stuff might change.
    So you might have a (over simplified here) table like this

    Typeid	        TypeName		TypeValue
    1		ActiveServerName	SQLDenisDB1
    1		DatabaseName		MyDB
    1		LogTableName		LogFileTable

    And there might be a dozen more configurations for a process
    In general people will do 3 selects if there are 3 values, let's take a look at what I mean. First create this table

    1. CREATE TABLE SomeConfigurations(Typeid INT NOT NULL,
    2.             TypeName VARCHAR(100),
    3.             TypeValue VARCHAR(100))
    4.  
    5. INSERT SomeConfigurations VALUES (1,'ActiveServerName','SQLDenisDB1')
    6. INSERT SomeConfigurations VALUES (1,'DatabaseName','MyDB')
    7. INSERT SomeConfigurations VALUES (1,'LogTableName','LogFileTable')



    One select per value

    This is what I usually see, one query for each value.

    1. DECLARE @ActiveServerName VARCHAR(100),
    2.         @DatabaseName VARCHAR(100),
    3.         @LogTableName VARCHAR(100)
    4.        
    5.  
    6. SELECT @ActiveServerName = TypeValue
    7. FROM SomeConfigurations
    8. WHERE Typeid =1
    9. AND TypeName = 'ActiveServerName'
    10.  
    11. SELECT @DatabaseName = TypeValue
    12. FROM SomeConfigurations
    13. WHERE Typeid =1
    14. AND TypeName = 'DatabaseName'
    15.  
    16. SELECT @LogTableName = TypeValue
    17. FROM SomeConfigurations
    18. WHERE Typeid =1
    19. AND TypeName = 'LogTableName'
    20.  
    21. SELECT @ActiveServerName,@DatabaseName,@LogTableName

    Okay so that is not really something I want to maintain. I guess if you get paid by lines of code written it makes you look good :-)
    Next up.. a different approach...



    Enter the pivot.

    Pivot was introduced in SQL Server 2005 and here is how you can change those three selects into one select

    1. DECLARE @ActiveServerName VARCHAR(100),
    2.         @DatabaseName VARCHAR(100),
    3.         @LogTableName VARCHAR(100)
    4.  
    5. SELECT @ActiveServerName = ActiveServerName,
    6. @DatabaseName = DatabaseName,
    7. @LogTableName = LogTableName
    8. FROM
    9. (SELECT TypeName,TypeValue
    10. FROM SomeConfigurations
    11. WHERE Typeid =1) AS pivTemp
    12. PIVOT
    13. (   MAX(TypeValue)
    14.     FOR TypeName IN (ActiveServerName,DatabaseName,LogTableName)
    15. ) AS pivTable
    16.  
    17. SELECT @ActiveServerName,@DatabaseName,@LogTableName

    I prefer that over those three selects any time. Not only is it less code but it is also faster because it touches the tables once. If you want to learn more about PIVOT and UNPIVOT, then visit the following books on line link: http://msdn.microsoft.com/en-us/library/ms177410.aspx



    If you are running software from the last century: case to the rescue

    Even for you people who are still on SQL Server 2000 there is a way to do this in one select, take a look at the query below

    1. DECLARE @ActiveServerName VARCHAR(100),
    2.         @DatabaseName VARCHAR(100),
    3.         @LogTableName VARCHAR(100)
    4.  
    5. SELECT
    6. @ActiveServerName   = MAX(CASE TypeName WHEN 'ActiveServerName' THEN TypeValue ELSE '' END),
    7. @DatabaseName       = MAX(CASE TypeName WHEN 'DatabaseName'     THEN TypeValue ELSE '' END),
    8. @LogTableName       = MAX(CASE TypeName WHEN 'LogTableName'     THEN TypeValue ELSE '' END)
    9. FROM SomeConfigurations
    10. WHERE Typeid =1
    11.  
    12. SELECT @ActiveServerName,@DatabaseName,@LogTableName

    And the same applies here as to pivot, this query will hit the table only one time.



    So in the end, which do you prefer?

    A) 3 selects (because you get paid by lines of code)
    B) Pivot (because nobody else understand pivot syntax, so this is job security)
    C) Case statement (because you are still running NT 4.0 with SQL Server 2000 SP4)




    *** Remember, if you have a SQL related question, try our Microsoft SQL Server Programming forum or our Microsoft SQL Server Admin forum

    About the Author

    User bio imageDenis has been working with SQL Server since version 6.5. Although he worked as an ASP/JSP/ColdFusion developer before the dot com bust, he has been working exclusively as a database developer/architect since 2002. In addition to English, Denis is also fluent in Croatian and Dutch, but he can curse in many other languages and dialects (just ask the SQL optimizer) He lives in Princeton, NJ with his wife and three kids.
    Social SitingsTwitterFacebookLinkedInHomePageFlickrLTD RSS Feed
    1688 views
    Instapaper

    4 comments

    Comment from: Scott R. [Visitor]
    Scott R. Denis,

    Great post in showing these T-SQL alternatives.

    We all have seen our share of option #1 - easy to understand and explain, but not the least number of code lines to run or maintain.

    The pivot option (#2) is interesting (clever - I wouldn't have thought of that solution), but not necessarily my favorite - it may be harder to explain how it works to others (Pivot operator is not as commonly used as other T-SQL operators) and harder to recall how it works a year later when you have to maintain the code – depending on how often you use and stay current on this approach in different apps. I may change my mind on this one over time, as it grows on me.

    I actually like the case option (#3) best, as it is easy (for me) to understand now (and I suspect in a year), fewer lines of code to maintain than option #1, usable on more versions of SQL Server (old and new), easy to expand to more parameters (only one extra line per new parameter in the same where clause set), and should be easy to explain how it works to others.

    From my lack of experience with the Pivot operator, I would have thought that the FOR TypeName IN ... clause in your Pivot example:

    FOR TypeName IN (ActiveServerName, DatabaseName, LogTableName)

    needed to have each of the three IN clause values in quotes (as would be used in a SELECT … WHERE … IN clause):

    FOR TypeName IN ('ActiveServerName', 'DatabaseName', 'LogTableName')

    But in trying your example, I find that not only does your example work just fine as shown, but it will NOT work if you use quotes! Learn something new every day!

    All in all, a good comparison and exposure to different ways of solving the same task. Thanks again!


    Scott R.
    05/20/10 @ 03:36
    Comment from: SQLDenis [Member] Email
    SQLDenis Scott,

    Thanks for your comment. The reason that PIVOT doesn't need quotes (I think) is that those now become column names and are not values anymore.

    The real reason I( added the CASE query is that PIVOT is a little intimidating at first, I still have to look up the syntax every single time I use it.

    Reminds me of user defined functions, I had to lookup the syntax for years...of course I would just copy an existing one and modify it...made life easier...BTW I do the same foe pivot...copy an existing one..change columns and table name and done
    05/20/10 @ 06:05
    Comment from: wqw [Visitor]
    wqw What we less advanced user of SQL prefer is to keep settings in a single row table with lots of columns, so that we don't have to break the keyboard typing just to query some config values :-))
    05/20/10 @ 07:25
    Comment from: SQLDenis [Member] Email
    SQLDenis wqw,

    That is also an option but becomes a pain in the neck to maintain because you will need to add a column every time you have to add some other configuration value
    05/20/10 @ 08:09

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