SpDev - SQL Server stored procedure debugger
Step through SQL Server stored procedures and scripts in VS Code. You get breakpoints, variables, a call stack across nested procedures, result sets, errors at the right line, and step back.
Debug a file
- Open a
.sql file with CREATE PROCEDURE … (or a script).
- Click ▶ Debug above it.
- Enter a connection string to a development database (stored in secret storage) and the parameter values.
- Step with F10 / F11 / Shift+F11, continue with F5, and use Step Back to go backwards.
- After a
SELECT has run, hover over *, SELECT or a column name to see the rows it returned.
- F10 on the last statement stops once more on
END, so you can see what it returned before the session ends.
SpDev runs your local file, including local versions of the procedures it calls, so you can edit and re-run without deploying.
Debug calls from your app
Add the SpDev.Runtime NuGet package to your app. EF Core:
builder.Services.AddSpDev(o => o.Enabled = builder.Environment.IsDevelopment());
builder.Services.AddDbContext<AppDb>((sp, o) => o.UseSqlServer(cs).UseSpDev(sp));
Dapper or plain ADO.NET:
await using var connection = new SqlConnection(cs).WithSpDev(serviceProvider);
var orders = await connection.QueryAsync<Order>("dbo.GetOrders", new { CustomerId = 1 }, commandType: CommandType.StoredProcedure);
Then run SpDev: Attach to Application, set breakpoints and use your app. A call whose procedure has no local .sql file runs the database version, and the Debug Console tells you so.
Requirements
- .NET 8 runtime or later (the CLI is bundled).
- SQL Server 2016 or later (uses FOR JSON; tested on SQL Server 2022) or Azure SQL Database.
Settings
| Setting |
Default |
|
spdev.stopOnEntry |
true |
Stop on the first statement |
spdev.stopOnErrors |
true |
Stop on uncaught SQL Server errors |
spdev.traceNestedProcedures |
true |
Use local files for procedures called with EXEC |
spdev.searchDirectories |
[] |
Extra folders with .sql files |
spdev.maxSteps |
20000 |
Snapshot limit per procedure call |
spdev.maxResultRows |
500 |
Rows captured per result set |
spdev.hosting |
auto |
temp never writes to the database; database is needed for user-defined types |
spdev.attachPort |
52341 |
Port for Attach to Application |
spdev.cliPath / spdev.dotnetPath |
|
Use a different CLI or dotnet |
How it works and limitations
SpDev runs an instrumented copy of your procedure that reports every variable before each statement, then replays the recording. You can't edit values mid-run or evaluate arbitrary expressions, and dynamic SQL isn't traced. Functions, triggers and procedures without a local .sql file run normally but aren't stepped into. Use a development database: your code really runs.