Author: way0utwest

  • Always restore with NORECOVERY

    Always, always, ALWAYS restore a SQL Server database with the NORECOVERY option.

    It’s trivial to switch the database online.

    Not trivial to recover from an accidental restore with RECOVERY (the default)

    ‘nuff said.

  • Lifehacking – Not such a good idea?

    I read the confessions of a recovering Lifehacker and thought it was an interesting read. It seems that the author has started to realize that while you can make some differences in the small stuff in your life, it’s just small stuff. It’s also important not to let the organization, or hack, or change, overwhelm the benefit you get from it.

    I try to make some small changes here and there, and I do want to be more efficient, but not if the efficiency cost takes away too much of the rest of my life. It’s a balance, and one that can be hard to find.

    There’s also an interesting discussion on Hacker News about the post.

  • Use Tools

    Fortunately building tools for IT is easier than this.

    As someone that works with Information Technology, I usually work on applications designed to make work easier. For example, we have accounting systems that ease the handling of debits and credits, they detect mistakes in data entry, and in general require less people to handle the accounting needs of many firms. Do we have less accountants?

    I suppose we might have less, but it seems that the finance departments, handling AP and AR in many companies is as large as I remember from my younger days. Perhaps the department is smaller than it might otherwise be, but it’s usually not small.

    In IT, we have all kinds of tools available to us that can help with our jobs. What’s more, we can create new tools as needed to do our jobs. Powershell or Perl scripting, Codeplex projects, and more are available to most of us to help us better manage systems. In SQL Server, we even have a built in framework, Policy Based Management, that helps us prevent changes or problematic configurations. If you find a third party tool that can help, you can make a case for its purchase, using the time savings translated to actual costs. One of those tools might really make your job more enjoyable..

    In theory, we ought to be able to manage many more systems per person than we used to. Does that many that we need less people? Perhaps, but it seems we grow systems fast enough that we still need to hire more staff in many environments.

    I so often see people working in IT fail to take advantage of all the tools we have to automate much of their jobs. They often tell me if they automate too much of their jobs, they won’t be needed and may get let go. Personally I think that’s an excuse not to exercise your skills, challenge your mind, and get rid of tedious work There’s no shortage of work to be done in most companies. If that’s true, why not use your tools to get rid of the tedious work and spend your time on something more interesting?

    Steve Jones


    The Voice of the DBA Podcasts

    We publish three versions of the podcast each day for you to enjoy.

  • The Tally Table and Expanding Rows

    Suppose you had some data like this:

    Class           Limit
    ————— ———–
    Calculus        5
    History         4
    Physics         2

    But what you really want is this:

    Class           Student
    ————— ———–
    Calculus       
    Calculus       
    Calculus       
    Calculus       
    Calculus       
    History        
    History        
    History        
    History        
    Physics        

    Physics        

    Where you have a placeholder for each student. This is a little contrived, but for the sake of the scenario, how do you actually expand the data in the first set to the second?

    An easy way is a cursor, but suppose you had a large school environment and you were doing this regularly, you might not want the performance hit of a cursor. Suppose you have some similar scenario, like slotting inventory or holding places for some large report? You would want a better solution.

    Setup

    Let’s first get a table ready for this.

    declare @Table table (
      Class varchar(15)
    , Limit int
    )
    ;
    
    insert into @Table 
      values ('Calculas',5)
           , ('History', 6)
           , ('Physics', 2)
    ;       
    

    A Tally Table

    I first saw this when Jeff Moden talked about this in his “The Numbers or Tally Table” article. It seemed like a neartidea, and he improved upon is in his next piece, finding a more efficient way to generate the data. An even more flexible idea that I like came from his Test Data Generator article, where he uses sys.columns to build a list as large as he would like. I found it to be a great idea, and this problem is a great way to apply it.

    Here’s a short look at the code that makes this work.

    SELECT TOP (4) RowNum = ROW_NUMBER() OVER(ORDER BY a.[Name])
     FROM sys.columns a, sys.columns b

    In this code, a cross join occurs between sys.columns and itself. With the addition of the ROW_NUMBER() function, and an order by, you can easily get a list of numbers. If I run this. I get:

    RowNum

    ——————–

    1

    2

    3

    4

    If I change my TOP value, I can get different rows:

    SELECT TOP (6) RowNum = ROW_NUMBER() OVER(ORDER BY a.[Name])
     FROM sys.columns a, sys.columns b

    RowNum

    ——————–

    1

    2

    3

    4

    5

    6

    To make this work for me in the original problem, I will use the limit value for my TOP in a subquery. However I can’t do a straight join, I need a CROSS APPLY, that will execute the right side of the CROSS apply for each input row from the left table.. It’s intended to be for table valued functions, but in this case, we’ll just return a table from the right side.

    The code looks like this:

    SELECT
      c.Class
    , 'Student' = ' '
    FROM (
    SELECT Class,Limit
    FROM @Table
    ) c
    CROSS APPLY (
    SELECT TOP (Limit) RowNum = ROW_NUMBER() OVER(ORDER BY a.[name])
    FROM sys.columns a, sys.columns b
    ) n

    What happens is that for each row, the derived table on the right side of the CROSS APPLY, returns a set of numbers which are then linked to the row on the left side of the CROSS APPLY.

    For the first row in @table, we have “Calculus” and “5”. When we apply this row to the subquery on the right side (SELECT TOP()…), we get these results:

    1

    2

    3

    4

    5

    When this is joined with the row and the c.Class returned, we end up with the same value being returned 5 times. That results in

    Calculus

    Calculus

    Calculus

    Calculus

    Calculus

    If this is repeated for each of the other rows, we get 4 and 2 rows from the right side of the CROSS APPLY returned, respectively.

    The final results are what we get at the top of this post.