Author: way0utwest

  • The End of Azure Data Studio

    I don’t know how many of you will be disappointed or impacted by this, but Azure Data Studio (ADS) is being retired, as of 6 Feb, 2025. It will be supported for a little over a year, until 28 Feb, 2026. On one hand I’m not surprised, and on the other, I’m a little shocked by this.

    I have written a number of articles on ADS, and shown how things work, as well as pointed out a number of things that don’t work well in the product or its extensions. These pieces have gotten a number of reads, and people have commented on them, so I wonder if there are a lot of you that are upset by this. Is this going to change the way you work? I will say that it will lightly change my work, as I do use ADS to connect to PostgreSQL, but not so much for SQL Server.

    I have tried to use ADS, but I just don’t like it. I don’t have a good reason, as it does a lot of what I need from a query tool. I think the port of the query and result experience from a real app like SSMS or Enterprise Manager or even isql/w is just a worse experience. I don’t like the ADS interface and it’s annoying to me.

    I suspect that many others feel the same way (other views from Deb and Kevin). They don’t like the ADS experience and prefer SSMS or some other tool. I know there’s been no shortage of complaints over the years about, and finally MS has listened. From first trying to get everyone to leave SSMS to forcing people to install ADS alongside SSMS and now to finally retiring the tool. I think it’s a good decision as people don’t want to lose SSMS and it’s hard to maintain two tools.

    We will still have VS Code, which I use often for other purposes. I haven’t spent much time with the mssql extension, but I need to as it’s been updated as of a few months ago and supposedly works better now. We’ll see.

    In the meantime, I won’t mourn ADS. It was a tool that had potential. I liked the idea of notebooks, I liked the fast startup. I just wish it were better implemented as a run-a-query-and-get-results application. I wish we had a cross platform editor that was simple and fast, but not one based on VSCode. One that’s written to just manage queries. Maybe they’ll rewrite isql/w in a modern way and port it to Linux.

    Steve Jones

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

    Note, podcasts are only available for a limited time online.

  • Adding Manual Relationships Between Tables in the TDM Subsetter

    I wrote about getting the Redgate Test Data Manager set up in 10 minutes before, and a follow up post on using your own backup. One of the things I didn’t show from my own database was that it had no FKs, so the subsetting didn’t quite work as I wanted.

    A previous post showed how add starting tables for the subsetter to look at, however that didn’t get me a good data set for testing. This post continues looking at the subsetter by adding manual relationships to our configuration.

    This is part of a series of posts on TDM. Check out the tag for other posts.

    Declaring a Relationship in the Options File

    In my previous post, I’d picked a starting table and had reduced the dbo.players table from 16564 to 1800. However, I only had player information. If I query my subset database, I see there is a player, but I have no batting statistics for this player.

    2025-01_0196

    This is because my table has no declared FKs in it. If I check the dbo.batting table, I can see only a PK.

    2025-01_0197

    Let’s fix this.

    Declaring Manual FK Relationships

    In the options file documentation, there is a section that notes manual relationships can be declared with a key called “manualRelationships”. If I copy/paste the example section into my options file, I’ll see this:

    2025-01_0198

    I don’t have a SourceTest table, so let me edit things. I’ll set a relationship between dbo.players.playerID and dbo.batting.playerID. This gives me the following in my options file.

    2025-01_0199

    Before I run my subsetter, here are the row counts by table.

    2025-01_0200

    I’ll re-run this subset command, which includes my option file at the end.

    rgsubset run --database-engine=sqlserver --source-connection-string="server=localhost;database=BB_FullRestore;Trusted_Connection=yes;TrustServerCertificate=yes" --target-connection-string="server=localhost;database=BB_Subset;Trusted_Connection=yes;TrustServerCertificate=yes" --target-database-write-mode Overwrite --options-file E:\Documents\git\TDM-Demos\rgsubset-options-bb.json

    When I do that, I know see these row counts. Note I now have batting rows.

    2025-01_0201

    My player query won’t work, so I still need to declare another relationship with the dbo.teams table. That is shown below:

    2025-01_0202

    I can re-run the same command above, and then I see this set of rowcounts (original on left, subset on right).

    2025-01_0203

    There is teams data, and if I re-run my queries from the top, I can see stats now.

    2025-01_0204

    Now I have a dataset that I can perform development work with in terms of players, teams, and batting.

    I can also add more relationships as needed, for example, I’ll add this section to include pitching, batting post, and fielding. Here’s my complete options file:

    {
      "jsonSchemaVersion": 1,
      "startingTables": [
        { 
          "table":
          {
            "schema": "dbo",
            "name": "players"
          },
          "filterClause": "birthState = 'CA'"
        }
      ],
      "manualRelationships": [
        {
          "sourceTable": 
            { 
              "schema": "dbo", 
              "name": "players"
            },
          "sourceColumns": [ "playerID" ],
          "targetTable": 
            { 
              "schema": "dbo", 
              "name": "batting" 
            },
          "targetColumns": [ "playerID" ]
         },
         {
            "sourceTable": 
              { 
                "schema": "dbo",
     
                "name": "batting"
              },
            "sourceColumns": [ "teamID", "yearID", "lgID" ],
            "targetTable": 
              { 
                "schema": "dbo", 
                "name": "teams" 
              },
            "targetColumns": [ "teamID", "yearID", "lgID" ]
           },
           {
              "sourceTable": 
                { 
                  "schema": "dbo", 
                  "name": "players"
                },
              "sourceColumns": [ "playerID" ],
              "targetTable": 
                { 
                  "schema": "dbo", 
                  "name": "battingpost" 
                },
              "targetColumns": [ "playerID"]
             },
             {
                "sourceTable": 
                  { 
                    "schema": "dbo", 
                    "name": "players"
                  },
                "sourceColumns": [ "playerID" ],
                "targetTable": 
                  { 
                    "schema": "dbo", 
                    "name": "pitching" 
                  },
                "targetColumns": [ "playerID"]
               },
               {
                  "sourceTable": 
                    { 
                      "schema": "dbo", 
                      "name": "players"
                    },
                  "sourceColumns": [ "playerID" ],
                  "targetTable": 
                    { 
                      "schema": "dbo",
     
                      "name": "fielding"
                    },
                  "targetColumns": [ "playerID"]
                 }
      ]
    }
    

    After re-running the subsetter, I have these row counts. Note there are rows in all the tables defined in the options file.

    2025-01_0205

    I can keep adding in more tables as needed to ensure the subsetter can walk down the data relationships I need in my database to produce a useable dev/test dataset that’s smaller than production.

    TDM can help your devs build better software and with the subsetter, this can create lots of agility to ensure the data you need to accurately build this software is available.

    Give TDM a try today from the repo and a trial, or contact one of our reps and get moving with help from our sales engineers.

    Video Walkthrough

    Check out a video of my demoing this below:

  • Creating a GitHub Actions Self-Hosted Runner

    I had to demo the Flyway Autopilot system recently and created a GitHub Actions runner as a part of that. This post documents how this went.

    First, if you go to the settings in a repo and click the Actions area, you see a Runners item. Click that. Notice I have no runners.

    2025-01_0235

    In the upper right corner, I can click a button to create one.

    2025-01_0236

    This gives me the instructions to get a new one. Note, these are PowerShell commands, and the first command doesn’t quite work right. Still, this is what I need.

    2025-01_0237

    I opened a CMD window and stared running these. Note, I need to repeat the change directory.

    2025-01_0238

    Now start PowerShell as the next commands are PoSh ones. When I copy the next command, it starts downloading a zip file. As of this writing, this is a 600-ish MB file.

    2025-01_0239

    Once this is done, you can run the next commands, which unzip and configure this. For the config, I just hit enter as I don’t have multiple groups or tags, and I leave it named as my machine. I also don’t bother to run this as a service.

    The last command runs the runner agent.

    2025-01_0240

    If I go back to the Runner screen in Settings, I see I have an idle agent set up.

    2025-01_0241

    And that’s it. If I pick one of my workflows in the Actions tab, I can run it and I’ll see the job started in my runner folder. Here are my actions with the Run workflow button on the right.

    2025-02_0284

    If I click this, I see the job start in the CLI.

    2025-02_0285

    If I get back to the Actions, I’ll see things in progress. As you can see, I was slow here.

    2025-02_0283

    That’s about it. Now I can run local automations in my repo that connect to things like local databases, which can be handy.

    Video Walkthrough

    I’ve got a video of this process if you want to watch it.

  • Extended Event Comfort

    I saw an interesting thread recently in the SQL Server Community Slack where someone posted about extended events (XE). They were asking about whether XE would have a problem with a situation. The problem wasn’t so interesting, but a quote from one of the responders was. The quote was:

    The best time to have learned Extended Events was ten years ago. The second best time is today.

    I love that, and I tend to agree. If you need to trace what is happening inside your SQL Server, you need to learn how to capture information with Extended Events. That’s the best way to dig into the details of how queries affect your system.

    It’s also hard. I know that whenever I need to use it, which is rare, I have to dig through some articles and docs to understand what thing I need to do. Even having some scripts hasn’t helped because it’s a sufficiently complex system that unless I use it regularly, I forget how all the filters, targets, events, etc. work.

    On one hand, I think it’s amazing, and on the other, it’s too hard to use. Even when I try the Extended Events profiler, it’s so different from Profiler that I find myself getting frustrated at times trying to dig through the information.

    I am curious how many of you think XE is easy to configure and if you use it often. What are the places it works well? For those of you that don’t use XE or haven’t learned, why not? Do you not have to trace what’s happening with queries in some detail? Or do you have another way that you dive deep into your system? Or do you not have the need?

    If you do want to learn more, we have a short Stairway Series on Extended Events to help you get started, as well as a few other articles. If you’re an expert, we’d love a few more on using XE in specific situations.

    Steve Jones

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

    Note, podcasts are only available for a limited time online.