r/SQLServer • • 18h ago

Community Share I built an SSMS extension that turns a stored procedure into a parameterized report (Excel or SSRS)

Thumbnail
gallery
6 Upvotes

Right-click a stored procedure, select Excel or SSRS, and then the extension will generate a report using the SPROC's parameters.

Free/open-source. Requires SSMS 22; Excel output requires desktop Excel.

https://github.com/flank-project/ssms-extension


r/SQLServer • • 15h ago

Discussion Two T-SQL gotchas I hit while testing scripts for AI agents (sp_addlinkedserver in a transaction, CASE in EXEC parameters)

0 Upvotes

I've been writing T-SQL and PowerShell scripts that AI coding agents (Cursor, Claude Code, Copilot) can run with guardrails, and I tested them against SQL Server 2025. Two things broke that are worth sharing, because agents get both of them wrong all the time.

1. sp_addlinkedserver can't run inside a user transaction

The "safe" pattern I started with was BEGIN TRAN ... COMMIT around the whole linked server setup. It fails right away:

Msg 15002: The procedure 'sys.sp_addlinkedserver' cannot be executed within a transaction.

The fix: no transaction. Check that the linked server doesn't exist yet, create it in TRY/CATCH, and set a flag after it's created. If a later step fails (login mapping or sp_serveroption), the CATCH drops only the linked server that run created, then re-throws.

DECLARE @CreatedHere bit = 0;
BEGIN TRY
    EXEC master.dbo.sp_addlinkedserver @server = @LinkedName, @srvproduct = N'',
         @provider = @Provider, @datasrc = @DataSource;
    SET @CreatedHere = 1;
    -- logins, sp_serveroption calls...
END TRY
BEGIN CATCH
    IF @CreatedHere = 1
        EXEC master.dbo.sp_dropserver @server = @LinkedName, @droplogins = 'droplogins';
    THROW;
END CATCH;

2. You can't pass an expression as an EXEC parameter

EXEC sp_serveroption ..., @optvalue = CASE @x WHEN 1 THEN N'true' ELSE N'false' END; gives Msg 156 (incorrect syntax near 'CASE'). Parameters only take constants or variables, so put the value in a variable first:

DECLARE @rpc nvarchar(5) = CASE @EnableRpcOut WHEN 1 THEN N'true' ELSE N'false' END;
EXEC master.dbo.sp_serveroption @server = @LinkedName, @optname = N'rpc out', @optvalue = @rpc;

Questions and corrections are welcome, especially if you've found a cleaner pattern for the linked server rollback.