Introducing sqlutil: A .NET CLI Tool for SQL Server Developers Who Live in the Terminal

March 04, 2026
Introducing sqlutil: A .NET CLI Tool for SQL Server Developers Who Live in the Terminal

If you do any significant amount of work with SQL Server, you know the drill. You need to check what columns are on a table. You need to find which stored procedures reference a particular column name. You want to export some data as INSERT scripts so you can move it to another database. You need to quickly compare two database schemas without spinning up a full diff tool.

So you open SSMS. You wait for it to load. You connect. You drill through the object explorer. You right-click on things. You wait some more.

There has to be a better way.

That's why I built sqlutil — a .NET CLI tool that gives you fast, command-line access to all the things you routinely do with SQL Server. No GUI required. Just install it, point it at your database, and run commands.

This Is the Resurrection of Shovel

sqlutil is actually the spiritual successor to a tool I built years ago called Shovel. Shovel scratched the same itch — quick command-line utilities for SQL Server without opening SSMS — but it had a few problems.

First, it was built on an older version of .NET and had drifted out of date. Second — and this eventually became the dealbreaker — it was Windows-only. I do a lot of my work on a Mac these days, and Shovel just wasn't going to work.

So rather than try to resurrect it, I rebuilt it from scratch for .NET 10 under a new name, added a bunch of new functionality, and published it properly as a NuGet tool. It runs on Windows, Mac, and Linux. If you were a Shovel user, you'll feel right at home. If you never heard of Shovel, no matter — sqlutil stands on its own.

Installing sqlutil

sqlutil is distributed as a .NET Tool via NuGet, so installing it is one command:

dotnet tool install Benday.SqlUtil -g

You'll need .NET 10 or later installed. If you don't have it, grab it from https://dotnet.microsoft.com/.

Once it's installed, you've got the sqlutil command available everywhere — on Windows, Mac, or Linux.

Getting Started: Save a Connection

Everything starts with a connection. Instead of typing your server name, database, and credentials on every single command, sqlutil lets you save named connections and reuse them.

To set up a default connection:

sqlutil addconnection /server:localhost /database:MyDatabase /default:true

Once you've done that, every command will use your default connection automatically. No more /connectionstring arguments on everything.

If you work with multiple databases, you can save additional named connections:

sqlutil addconnection /name:staging /server:staging-server /database:MyDatabase

Then pass /connectionname:staging on any command to use it.

Favorite Feature #1: searchcolumndata

I want to lead with this one because it's the feature I keep coming back to, and honestly, it's the reason I originally built Shovel in the first place.

Here's the scenario. You're working in an unfamiliar codebase. You're looking at a screen in the app and you see a value — maybe it's a status label, a reference code, a category name, something. And you need to figure out where that value is coming from in the database.

The problem is: you have no idea. It could be literally anywhere. You don't know the schema well enough to guess. You could spend twenty minutes clicking around in SSMS trying to find it, or you could just run this:

sqlutil searchcolumndata /search:"Pending Approval"

sqlutil will scan every table, every text column, looking for that value and tell you exactly where it lives. Table name, column name, right there.

You can narrow the search if you have a guess about which table it might be in:

sqlutil searchcolumndata /table:Order% /search:"Pending Approval"

This is the kind of tool that pays for itself the first time you're dropped into a legacy system with no documentation and a production bug to fix. Instead of spending an hour reverse-engineering the schema, you spend thirty seconds running a search and you know exactly where to look.

Favorite Feature #2: exportdata

Here's the other scenario I run into constantly. I've got data in one database that I need to get into a different database. Maybe it's reference data that needs to be in the staging environment. Maybe it's a set of lookup values I need to seed into a new database. Maybe I'm setting up a dev environment and need realistic data to work with.

The old approach: open SSMS, right-click the table, use the "Script data as INSERT" wizard, tweak the output, run it somewhere else. It works, but it's a lot of steps and the wizard gives you the whole table whether you want that or not.

The sqlutil approach: write the SELECT query you actually want and let exportdata generate the script.

sqlutil exportdata /query:"SELECT * FROM LookupValues WHERE Type = 'Status'" /scripttype:insert /filename:status-data.sql

You get three output formats:

  • insert — standard INSERT statements
  • identityinsert — INSERT with IDENTITY INSERT ON/OFF wrappers for when you need to preserve the primary key values
  • mergeinto — a MERGE statement that inserts or updates based on whether the row already exists

The MERGE option is the one I reach for most often. If you're moving data between environments repeatedly — like keeping a reference table in sync between dev and staging — a MERGE script is idempotent. You can run it as many times as you want and it'll do the right thing.

sqlutil exportdata /query:"SELECT * FROM ProductCategories" /scripttype:mergeinto /filename:categories.sql

You can skip the /filename argument and it'll write to stdout if you want to pipe it somewhere or just look at it.

What Else Can sqlutil Do?

Schema Introspection

sqlutil listtables gives you a quick list of every table in the database. sqlutil describetable /table:Customer shows you all the columns and their data types for a specific table. sqlutil listdatabases lists all the databases on your SQL Server instance.

These are the things you're constantly doing manually in SSMS. Having them as quick CLI commands makes a real difference in your daily workflow.

Search

Beyond searchcolumndata, sqlutil has a full suite of search commands for when you're trying to understand an unfamiliar schema.

sqlutil searchtables /search:order finds all tables with "order" in the name. sqlutil searchcolumns /search:CustomerId finds every table with a column matching that name — great when you're tracing foreign key relationships through a schema you didn't build. sqlutil searchproccode /search:DeletedDate searches stored procedure source code for a text pattern, so you can find every proc that touches a particular column.

sqlutil searchcolumns /search:CustomerId
sqlutil searchproccode /search:DeletedDate
sqlutil searchprocs /search:usp_Order

Together, these commands let you get oriented in an unfamiliar database pretty quickly.

Query

sqlutil runquery lets you fire off an ad-hoc SQL query straight from the command line:

sqlutil runquery /query:"SELECT TOP 10 * FROM Customer ORDER BY CreatedDate DESC"

Add /filename:output.csv to write the results to a CSV file instead of stdout.

Database Comparison

sqlutil comparedb does a full schema comparison between two databases — tables, views, stored procedures, functions, and foreign keys. comparetables and compareprocs let you narrow it if you only care about one category.

sqlutil comparedb /connectionname1:dev /connectionname2:staging

Useful for validating that your dev and staging databases are in sync, or for spotting what changed between deployments.

Session Management

sqlutil listsessions shows you the active sessions on your SQL Server instance — handy when you need to know who's connected before doing maintenance work.

There's a GUI Too (and It's Kind of Interesting)

If you want a point-and-click interface without memorizing command syntax, run:

sqlutil gui

This one's worth explaining a little because it's not just a hand-built UI. I recently added a feature to my Benday.CommandsFramework NuGet package that can generate a basic Blazor GUI on the fly, directly from the command definitions. So sqlutil gui isn't a separate app — it reads the same command metadata that drives the CLI and spins up a Blazor interface automatically.

It's useful if you're sharing sqlutil with someone who's less comfortable on the command line, or if you just want to explore what's available without reading documentation.

Why a .NET Tool?

I spend a lot of my time working with .NET teams on Azure DevOps, GitHub, and delivery problems. The people on those teams are living in terminals and editors. A .NET Tool distributes cleanly via NuGet, works on Windows, Mac, and Linux, stays up to date with dotnet tool update, and doesn't require any installation ceremony.

It fits naturally into the workflow of a .NET developer in a way that a standalone installer doesn't. Shovel was always an awkward download-and-extract situation — and Windows-only. sqlutil is one command and you're done, on whatever platform you're on.

Get It

sqlutil is available on NuGet at https://www.nuget.org/packages/Benday.SqlUtil.

The source code and full documentation are on GitHub at https://github.com/benday-inc/sqlutil. If you run into a bug or have an idea for a command you'd like to see, submit an issue.

Give it a try and let me know what you think.

-Ben

Categories: sql-server dotnet