How Often Do You Patch?

I saw two things recently. First, CU25 for SQL Server 2017 was released. I realized that I was CU8 locally, so I had work to do. Second, I noticed that SQL Server 2016 fell out of mainstream support on 13 Jul, 2021. Amazing that it’s been around for 5 years already and has moved into Extended support. We’ll still get security updates, but nothing will be fixed from that version, which it seems many people are running.

Microsoft also announced they will put out a final Service Pack for SQL Server 2016. I am glad to see that, as I’ve often wanted to know there is a final patch that is released for each version, as I can know when I’m done patching.

Today I’m wondering if you track this at all. Do you actively look to ensure your instances are patched? Are you on a schedule of some sort, maybe matching Microsoft’s every-other-month pace, or perhaps just a few times a year? Or is this more ad hoc?  When I go visit companies, I often find instances at all different levels, often without any reasoning as to why systems aren’t consistently patched.

I used to try and ensure we patched every quarter, though certainly, I faced resistance from some business owners of systems over the worry that a patch might break something. Valid concerns back then, and still somewhat valid today, though if a patch gets through a few months without reports of issues, it’s probably safe for most systems. Still, make sure you test, especially for business critical workloads.

These days, with so many hacking attempts, ransomware distribution channels, and no end to phishing, it makes sense to stay on top of patches and make sure you are up to date or at least planning to do so. Some of the high-profile hacks, like the Equifax one, have occurred on systems where patches were available but not applied. I don’t know that many of the patches are closing holes in SQL Server, but there are definitely issues with Windows where you would want to ensure your host OS was patched. Maybe that’s something you ought to check on today and ensure you have a plan to apply those updates.

Steve Jones

Listen to the podcast at Libsyn, Stitcher, Spotify, or iTunes.

Posted in Editorial | Tagged , | 2 Comments

Daily Coping 23 Jul 2021

I started to add a daily coping tip to the SQLServerCentral newsletter and to the Community Circle, which is helping me deal with the issues in the world. I’m adding my responses for each day here. All my coping tips are under this tag. 

Today’s tip is to take a break and do something for yourself.

I’m actually taking a break tomorrow. After the world’s longest volleyball season, we said goodbye to kids in Orlando at our last tournament. It was a bit rushed, not all parents were there, and it felt a little incomplete.

Tomorrow we set up an end of year party. This is late, especially as most kids are already on a team for next year, and back to their summer lives and involved with their high school teams. However, we’re getting together, and while I’ll do some chores, I’ll take a break and spend some time just having fun, reminiscing with everyone and closing out the 10+ months I spent with these kids every week.

Posted in Blog | Tagged , , | Comments Off on Daily Coping 23 Jul 2021

Daily Coping 22 Jul 2021

I started to add a daily coping tip to the SQLServerCentral newsletter and to the Community Circle, which is helping me deal with the issues in the world. I’m adding my responses for each day here. All my coping tips are under this tag. 

Today’s tip is to let go of small stuff and focus on something that matters.

Small stuff is just that. It’s not really important in life. I’m very blessed in that most of my life is pretty perfect. There are little things that annoy me, but they are little.

Last week I lost my wallet. I ran some errands, used a card, and the next day realized I didn’t have my wallet. I didn’t see any fraudulent charges when I turned off all my cards. I searched all over the house, but couldn’t find it anywhere. It really annoyed me, more than it should. There were a few hundred dollars in various currencies in there, and a number of credit cards, but nothing that was really that important.

After a few hours of looking, I gave up and started replacing cards and my license. I had to decide to stop being upset and just move on with life. The important things that day were spending some time with family, and this wasn’t enough of a problem to interrupt that.

All in all, it’s a minor hiccup in life, no matter how annoying at the time.

Posted in Blog | Tagged , , | Comments Off on Daily Coping 22 Jul 2021

Using Aggregates in Calculations with Other Columns Functions–#SQLNewBlogger

Another post for me that is simple and hopefully serves as an example for people trying to get blogging as #SQLNewBloggers.

In the last post on Window functions, I looked at ROW_NUMBER, and how I can use this to order rows. In this one, I want to look at one of the advantages of Window functions in trying to combine data and aggregates together.

A Scenario

In the last post, I examined the career of Ken Griffey, Jr., showing his home runs with some ordering. That wasn’t a very realistic case of using data, so let’s look at another one. Suppose I want to know the percentage of his career home runs he hit during each one of his seasons. That’s an interesting question, showing some idea of how much he improved or declined. If I try a to start combining a “normal” aggregate with other data, I can’t do it without a GROUP BY.

2021-07-19 15_27_35-window_queries.sql - ARISTOTLE.BaseballData (ARISTOTLE_Steve (57))_ - Microsoft

Not a huge big deal, as I can put the sum in a CTE and use it later. Here’s the code:

WITH cteHR (PlayerID, TotalHR)
AS (   SELECT
                 b.playerID
               , SUM (hr)
        FROM     dbo.batting AS b
        WHERE    b.playerID = 'griffke02'
        GROUP BY b.playerID)
SELECT
                b.yearID
              , b.teamID
              , hr
              , TotalHR
              , ROUND((hr * 1.0) / TotalHR * 100, 2) AS percentofCareer
FROM
                dbo.batting AS b
     INNER JOIN cteHR
         ON cteHR.PlayerID = b.playerID
WHERE          b.playerID = 'griffke02'
ORDER BY       b.yearID;

And the results.

2021-07-19 15_30_52-window_queries.sql - ARISTOTLE.BaseballData (ARISTOTLE_Steve (57))_ - Microsoft

That’s OK, but the code is complex, and if I wanted to break the home runs by team or some other group, it would get more complex quickly.

Window Functions Simplify Things

Here’s a simpler query. I’ve just added the SUM with an OVER() clause, without any order. I just want all rows summed. I added this to the query to see the value.

SELECT
          b.yearID
        , TeamID
        , HR
        , SUM (b.hr) OVER (ORDER BY (SELECT NULL)) AS TotalHR
        , ROUND ((b.HR * 1.0) / SUM (b.hr) OVER (ORDER BY (SELECT NULL))  * 100, 2) AS TeamPercentofCareer
FROM     dbo.batting AS b
WHERE    b.playerID = 'griffke02'
ORDER BY b.yearID;

The results are the same as the other query, but it’s easy to see.

What if I wanted to change this and order this by the highest percentage years of his career. In other words, when was he the most productive. I can easily add an ORDER BY to both queries to see this, but I lose some context.

Look at these results. How do I know if 1997 was closed to the beginning or end of his career?

2021-07-19 15_35_33-window_queries.sql - ARISTOTLE.BaseballData (ARISTOTLE_Steve (57))_ - Microsoft

I want to add some context with the span of his career. I can do that easily with a few more Window functions. Here’s the result I want, with the years showing his career first. I moved some of the other data to the end.

2021-07-19 15_38_57-window_queries.sql - ARISTOTLE.BaseballData (ARISTOTLE_Steve (57))_ - Microsoft

Without window functions, this would be complex, as the MIN() and MAX() would be from different columns, so I’d need another CTE. Here, I can use this code:

SELECT
        CAST(MIN (b.yearID) OVER (ORDER BY (SELECT NULL)) AS CHAR(4)) 
        + '-'
        + CAST(MAX (b.yearID) OVER (ORDER BY (SELECT NULL)) AS CHAR(4)) AS CareerSpan
        , b.yearID
        , ROUND ((b.HR * 1.0) / SUM (b.hr) OVER (ORDER BY (SELECT NULL))  * 100, 2) AS TeamPercentofCareer
        , TeamID
        , HR
        , SUM (b.hr) OVER (ORDER BY (SELECT NULL)) AS TotalHR
FROM     dbo.batting AS b
WHERE    b.playerID = 'griffke02'
ORDER BY TeamPercentofCareer desc;

If I wanted to add some math, like how many years into his career was he, I could easily do that. Here I’ve added the year number to his career, which comes from ROW_NUMBER().

2021-07-19 15_42_31-window_queries.sql - ARISTOTLE.BaseballData (ARISTOTLE_Steve (57))_ - Microsoft

The code? I just add the aggregates I need, which in this case are ones containing the entire set. I mix MIN(), MAX(), COUNT() and ROW_NUMBER(), and use a partition of the entire data set.

SELECT
        CAST(MIN (b.yearID) OVER (ORDER BY (SELECT NULL)) AS CHAR(4)) 
        + '-'
        + CAST(MAX (b.yearID) OVER (ORDER BY (SELECT NULL)) AS CHAR(4)) AS CareerSpan
        , b.yearID
        , ROUND ((b.HR * 1.0) / SUM (b.hr) OVER (ORDER BY (SELECT NULL))  * 100, 2) AS TeamPercentofCareer
        , RTRIM(CAST(ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS CHAR(2)) )
        + ' of ' 
        + CAST( COUNT(yearid) OVER(ORDER BY (SELECT NULL)) AS CHAR(2))
        AS YearInCareer
        , TeamID
        , HR
        , SUM (b.hr) OVER (ORDER BY (SELECT NULL)) AS TotalHR
FROM     dbo.batting AS b
WHERE    b.playerID = 'griffke02'
ORDER BY TeamPercentofCareer desc;

Try doing that without window functions. It’s a nightmare to write in T-SQL.

SQLNewBlogger

This was pretty easy to write. The hard part was thinking of the questions I might ask of this data set and setting up the queries. Duplicating this without window functions was fun, and took more time. But it was good practice for me, and helped me to better understand why I like window functions.

This took me about 30 minutes, and it’s a good showcase of learning a new technique and applying it. You should do this if writing reports and aggregates is part of your job and you might want to showcase this to your next potential employer.

Posted in Blog | Tagged , , | 2 Comments