Not every Copilot task needs a trust-but-verify lecture. Some things are low-stake enough that the speed boost is pure upside.
Here are the quick wins I've found genuinely useful — tasks where Copilot saves time and the risk of getting burned is close to zero.
If you want to follow along:
CREATE TABLE dbo.Trades (
TradeID INT IDENTITY(1,1) PRIMARY KEY,
Symbol VARCHAR(10) NOT NULL,
Quantity INT NOT NULL,
Price DECIMAL(10,4) NOT NULL,
TradeDate DATE NOT NULL,
TraderID INT NOT NULL
);
INSERT INTO dbo.Trades (Symbol, Quantity, Price, TradeDate, TraderID) VALUES
('AAPL', 500, 178.25, '2024-01-15', 101),
('AAPL', 300, 182.50, '2024-02-20', 101),
('MSFT', 400, 378.00, '2024-01-22', 102),
('MSFT', 250, 385.50, '2024-02-28', 103),
('GOOGL', 150, 141.20, '2024-01-30', 102);
1. Boilerplate CRUD
Need a quick stored procedure for basic insert/update operations? Copilot handles the tedium:
"Create an insert procedure for dbo.Trades with parameters for Symbol, Quantity, Price, TradeDate, and TraderID."
-- Created by GitHub Copilot in SSMS - review carefully before executing
/*
Purpose: Insert a row into dbo.Trades.
Accepts Symbol, Quantity, Price, TradeDate, TraderID.
Returns new TradeID in output parameter @NewTradeID.
*/
CREATE OR ALTER PROCEDURE dbo.usp_InsertTrade
@Symbol VARCHAR(10),
@Quantity INT,
@Price DECIMAL(10,4),
@TradeDate DATE,
@TraderID INT,
@NewTradeID INT OUTPUT
AS
BEGIN
SET NOCOUNT ON;
-- Basic parameter validation
IF @Symbol IS NULL OR LTRIM(RTRIM(@Symbol)) = ''
BEGIN
RAISERROR('Symbol is required',16,1);
RETURN;
END
INSERT INTO dbo.Trades (Symbol, Quantity, Price, TradeDate, TraderID)
VALUES (@Symbol, @Quantity, @Price, @TradeDate, @TraderID);
SET @NewTradeID = CAST(SCOPE_IDENTITY() AS INT);
END;
Didn't ask for that @NewTradeID, but not too bad otherwise. Thirty seconds saved.
2. Syntax You Rarely Use
I don't write PIVOT queries often enough to remember the syntax cold. Instead of Googling and wading through Stack Overflow, let's ask Copilot:
"Pivot the Trades table to show total quantity by symbol as columns, with TraderID as rows."
-- Created by GitHub Copilot in SSMS - review carefully before executing
DECLARE @cols NVARCHAR(MAX), @select NVARCHAR(MAX), @sql NVARCHAR(MAX);
SELECT @cols = STRING_AGG(QUOTENAME(Symbol), ',')
FROM (SELECT DISTINCT Symbol FROM dbo.Trades) s;
SELECT @select = STRING_AGG('ISNULL(' + QUOTENAME(Symbol) + ',0) AS ' + QUOTENAME(Symbol), ', ')
FROM (SELECT DISTINCT Symbol FROM dbo.Trades) s;
IF @cols IS NULL
BEGIN
PRINT N'No rows found in dbo.Trades; nothing to pivot.';
RETURN;
END
SET @sql = N'SELECT TraderID, ' + @select + N'
FROM (
SELECT TraderID, Symbol, Quantity FROM dbo.Trades
) src
PIVOT (
SUM(Quantity) FOR Symbol IN (' + @cols + N')
) p
ORDER BY TraderID;';
EXEC sp_executesql @sql;
Results:
| TraderID | AAPL | GOOGL | MSFT |
|---|---|---|---|
| 101 | 800 | 0 | 0 |
| 102 | 0 | 150 | 400 |
| 103 | 0 | 0 | 250 |
I asked for a simple pivot. Copilot gave me a dynamic version that handles any symbols in the table, with NULL handling and error checking. Overkill? Maybe. But it works, and I didn't have to remember any of it.
Same goes for MERGE statements, recursive CTEs, windowing functions with ROWS BETWEEN — anything you use just often enough to forget the exact syntax.
3. Explaining Ugly Execution Plans
This is where Copilot genuinely shines.
Point it at a 47-operator execution plan and ask: "Why is this slow?"
You'll get a plain-English summary of the key cost drivers: the hash match spilling to tempdb, the scan instead of seek, the missing index hint buried in the XML. It's a solid first pass that would take you 20-ish minutes to piece together manually.
Not always right. But usually right enough to get things moving and save a little time.
4. Quick Environment Discovery
New client. Unfamiliar instance. You need the lay of the land fast.
"What's the recovery model and last backup time for all databases on this instance?"
-- Created by GitHub Copilot in SSMS - review carefully before executing
SELECT
d.name AS DatabaseName,
d.recovery_model_desc AS RecoveryModel,
last_full.last_backup AS LastFullBackup,
last_diff.last_backup AS LastDiffBackup,
last_log.last_backup AS LastLogBackup,
last_any.last_backup AS LastAnyBackup
FROM sys.databases AS d
OUTER APPLY (
SELECT MAX(backup_finish_date) AS last_backup
FROM msdb.dbo.backupset bs
WHERE bs.database_name = d.name AND bs.type = 'D'
) last_full
OUTER APPLY (
SELECT MAX(backup_finish_date) AS last_backup
FROM msdb.dbo.backupset bs
WHERE bs.database_name = d.name AND bs.type = 'I'
) last_diff
OUTER APPLY (
SELECT MAX(backup_finish_date) AS last_backup
FROM msdb.dbo.backupset bs
WHERE bs.database_name = d.name AND bs.type = 'L'
) last_log
OUTER APPLY (
SELECT MAX(backup_finish_date) AS last_backup
FROM msdb.dbo.backupset bs
WHERE bs.database_name = d.name
) last_any
ORDER BY d.name;
Results:
| DatabaseName | RecoveryModel | LastFullBackup | LastDiffBackup | LastLogBackup | LastAnyBackup |
|---|---|---|---|---|---|
| CRM_Prod_RPT_BBDW | SIMPLE | 2025-12-31 11:10:27 | NULL | NULL | 2025-12-31 11:10:27 |
| DBA | FULL | 2025-12-03 08:15:14 | NULL | NULL | 2025-12-03 08:15:14 |
| IOTestDB | FULL | NULL | NULL | NULL | NULL |
| master | SIMPLE | NULL | NULL | NULL | NULL |
| model | FULL | NULL | NULL | NULL | NULL |
| msdb | SIMPLE | NULL | NULL | NULL | NULL |
| tempdb | SIMPLE | NULL | NULL | NULL | NULL |
I asked for recovery model and last backup. Copilot gave me full, diff, log, and "any" backup dates with OUTER APPLY. Overkill? A little. But those yellow NULL highlights in my results grid told me exactly which databases need attention.
Discovery queries like this are basically free. The risk is near zero; the time savings is real.
The Pattern
Low-stakes. Well-defined. Easily verified at a glance.
That's the sweet spot. Save your skepticism for the complex stuff — the multi-table joins, the performance-critical queries, the business logic that matters.
For the rest? Let the robot handle the tedium.
No comments:
Post a Comment