sqlserver
Use when writing T-SQL, editing SQL Server .sql files, using sqlcmd, SQL Server connection strings, stored procedures, execution plans, indexes, Always On, JSON, security, or connector code.
Best use case
sqlserver is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
Use when writing T-SQL, editing SQL Server .sql files, using sqlcmd, SQL Server connection strings, stored procedures, execution plans, indexes, Always On, JSON, security, or connector code.
Teams using sqlserver should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/sqlserver/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How sqlserver Compares
| Feature / Agent | sqlserver | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
Use when writing T-SQL, editing SQL Server .sql files, using sqlcmd, SQL Server connection strings, stored procedures, execution plans, indexes, Always On, JSON, security, or connector code.
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# SQL Server
Microsoft SQL Server is a relational database engine spanning on-premises, containers, and Azure SQL. This skill covers T-SQL development, performance tuning, high availability, security, and connectivity across all major languages.
## Quick Reference
### Connection Setup (Python pyodbc)
```python
import pyodbc
conn_str = (
"DRIVER={ODBC Driver 18 for SQL Server};"
"SERVER=myserver.database.windows.net,1433;"
"DATABASE=mydb;"
"UID=myuser;PWD=mypassword;"
"Encrypt=yes;TrustServerCertificate=no;"
)
conn = pyodbc.connect(conn_str)
cursor = conn.cursor()
# Always use parameterized queries
cursor.execute("SELECT OrderID, Total FROM Orders WHERE CustomerID = ?", (42,))
rows = cursor.fetchall()
```
### Stored Procedure Template
```sql
CREATE OR ALTER PROCEDURE dbo.usp_GetCustomerOrders
@CustomerID INT,
@StartDate DATE = NULL, -- optional with default
@TotalCount INT OUTPUT -- output parameter
AS
BEGIN
SET NOCOUNT ON;
BEGIN TRY
SELECT OrderID, OrderDate, Total
FROM Orders
WHERE CustomerID = @CustomerID
AND (@StartDate IS NULL OR OrderDate >= @StartDate)
ORDER BY OrderDate DESC;
SET @TotalCount = @@ROWCOUNT;
END TRY
BEGIN CATCH
THROW;
END CATCH
END;
GO
```
### Index Patterns
```sql
-- Clustered index (one per table, defines physical order)
CREATE CLUSTERED INDEX IX_Orders_OrderDate ON Orders(OrderDate);
-- Non-clustered covering index (INCLUDE avoids key lookups)
CREATE NONCLUSTERED INDEX IX_Orders_CustomerID
ON Orders(CustomerID)
INCLUDE (OrderDate, Total);
-- Filtered index (partial index for common queries)
CREATE NONCLUSTERED INDEX IX_Orders_Active
ON Orders(Status)
WHERE Status = 'Active';
```
### Key T-SQL Patterns
```sql
-- CTE with window function
WITH RankedOrders AS (
SELECT
CustomerID, OrderID, Total,
ROW_NUMBER() OVER (PARTITION BY CustomerID ORDER BY Total DESC) AS RowNum
FROM Orders
)
SELECT CustomerID, OrderID, Total
FROM RankedOrders
WHERE RowNum = 1;
-- MERGE upsert
MERGE INTO Inventory AS tgt
USING @Updates AS src ON tgt.ProductID = src.ProductID
WHEN MATCHED THEN UPDATE SET tgt.Qty = src.Qty
WHEN NOT MATCHED THEN INSERT (ProductID, Qty) VALUES (src.ProductID, src.Qty);
-- Offset pagination (2012+)
SELECT OrderID, OrderDate, Total
FROM Orders
ORDER BY OrderDate DESC
OFFSET @PageSize * (@PageNum - 1) ROWS
FETCH NEXT @PageSize ROWS ONLY;
```
<workflow>
## Workflow
### Step 1: Identify the Pattern
| Need | Go to | Key Concept |
| --- | --- | --- |
| Write a complex query | tsql_patterns.md | CTEs, window functions, APPLY |
| Build a stored procedure | stored_procedures.md | SET NOCOUNT ON, TRY/CATCH |
| Query is slow | performance.md | Execution plans, Query Store |
| Connect from app code | connections.md | Parameterized queries, drivers |
| Work with JSON data | json.md | JSON_VALUE, OPENJSON, FOR JSON |
| Lock down access | security.md | RLS, Dynamic Data Masking |
| Backup, maintain, monitor | admin.md | DBCC, DMVs, SQL Agent |
| HA / DR architecture | availability.md | Always On AG, FCI |
### Step 2: Implement
1. Use parameterized queries for all external input -- never concatenate strings
2. Start stored procedures with `SET NOCOUNT ON` to suppress row count messages
3. Wrap DML in explicit transactions with `TRY/CATCH` and `THROW`
4. Add covering indexes (`INCLUDE` columns) to eliminate key lookups
5. Test with actual execution plans (`SET STATISTICS XML ON` or SSMS Ctrl+M)
### Step 3: Validate
Run through the validation checkpoint below before considering the work complete.
</workflow>
<guardrails>
## Guardrails
- **Always use parameterized queries**: `?` placeholders in pyodbc, `@Param` in T-SQL -- never string concatenation
- **Always SET NOCOUNT ON** in stored procedures -- reduces network traffic and prevents DONE_IN_PROC interference
- **Always use TRY/CATCH** for error handling in procedures -- use `THROW` (not `RAISERROR`) for re-throwing
- **Always use `CREATE OR ALTER`** (2016 SP1+) instead of DROP/CREATE to preserve permissions
- **Prefer inline TVFs** over multi-statement TVFs and scalar UDFs -- multi-statement TVFs prevent parallelism
- **Prefer `OFFSET/FETCH`** over `ROW_NUMBER()` for simple pagination (2012+)
- **Never use `SELECT *`** in production queries -- always specify columns explicitly
- **Never use cursors** unless no set-based alternative exists -- set-based operations are orders of magnitude faster
</guardrails>
<validation>
### Validation Checkpoint
Before delivering SQL Server code, verify:
- [ ] All user input passes through parameterized queries (no string concatenation)
- [ ] Stored procedures have `SET NOCOUNT ON` as the first statement
- [ ] DML operations are wrapped in `BEGIN TRY / BEGIN CATCH` with `THROW`
- [ ] Indexes include `INCLUDE` columns to cover common query patterns
- [ ] No implicit conversions in WHERE clauses (match data types exactly)
- [ ] `CREATE OR ALTER` used instead of `DROP`/`CREATE` where supported
</validation>
<example>
## Example
**Task:** "Create a stored procedure to search orders by customer and date range, with a Python caller using parameterized queries."
```sql
-- T-SQL: Stored procedure with proper error handling
CREATE OR ALTER PROCEDURE dbo.usp_SearchOrders
@CustomerID INT,
@StartDate DATE = NULL,
@EndDate DATE = NULL,
@PageNum INT = 1,
@PageSize INT = 50
AS
BEGIN
SET NOCOUNT ON;
BEGIN TRY
SELECT
o.OrderID,
o.OrderDate,
o.Total,
c.CustomerName
FROM Orders o
INNER JOIN Customers c ON c.CustomerID = o.CustomerID
WHERE o.CustomerID = @CustomerID
AND (@StartDate IS NULL OR o.OrderDate >= @StartDate)
AND (@EndDate IS NULL OR o.OrderDate <= @EndDate)
ORDER BY o.OrderDate DESC
OFFSET @PageSize * (@PageNum - 1) ROWS
FETCH NEXT @PageSize ROWS ONLY;
END TRY
BEGIN CATCH
THROW;
END CATCH
END;
GO
```
```python
# Python: Parameterized call via pyodbc
import pyodbc
conn = pyodbc.connect(
"DRIVER={ODBC Driver 18 for SQL Server};"
"SERVER=myserver,1433;DATABASE=mydb;"
"UID=myuser;PWD=mypassword;"
"Encrypt=yes;TrustServerCertificate=no;"
)
cursor = conn.cursor()
cursor.execute(
"EXEC dbo.usp_SearchOrders @CustomerID=?, @StartDate=?, @PageNum=?, @PageSize=?",
(42, "2025-01-01", 1, 25),
)
for row in cursor.fetchall():
print(row.OrderID, row.OrderDate, row.Total, row.CustomerName)
cursor.close()
conn.close()
```
</example>
## References Index
For detailed guides and code examples, refer to the following documents in `references/`:
- **[T-SQL Patterns](references/tsql_patterns.md)** -- Window functions, CTEs, MERGE, APPLY, PIVOT, temporal tables, pagination.
- **[Stored Procedures & T-SQL Programming](references/stored_procedures.md)** -- Procedures, functions, error handling, transactions, cursors, dynamic SQL, triggers.
- **[Performance Tuning](references/performance.md)** -- Execution plans, Query Store, indexing strategy, wait stats, parameter sniffing, deadlocks.
- **[Connection Patterns](references/connections.md)** -- Python, Node.js, .NET, Java, Go drivers; connection strings; Azure AD / Managed Identity.
- **[JSON in SQL Server](references/json.md)** -- JSON_VALUE, OPENJSON, FOR JSON, computed-column indexing, JSON type (2022+/2025).
- **[Security](references/security.md)** -- RLS, Dynamic Data Masking, Always Encrypted, TDE, auditing, roles and permissions.
- **[Administration](references/admin.md)** -- Backup/restore, DBCC, maintenance, SQL Agent, DMV monitoring, server configuration.
- **[High Availability & DR](references/availability.md)** -- Always On AG, FCI, log shipping, Azure SQL geo-replication, contained AGs.
- **[Columnstore & Analytics](references/columnstore.md)** -- Columnstore indexes, batch mode, HTAP patterns, In-Memory OLTP.
- **[CLI & Tools](references/sqlcmd.md)** -- sqlcmd, SSMS, Azure Data Studio, dbatools, sp_whoisactive, Ola Hallengren.
## Official References
- <https://learn.microsoft.com/en-us/sql/sql-server/>
- <https://learn.microsoft.com/en-us/sql/t-sql/language-reference>
- <https://learn.microsoft.com/en-us/azure-data-studio/>
## Shared Styleguide Baseline
- Use shared styleguides for generic language/framework rules to reduce duplication in this skill.
- [General Principles](https://github.com/cofin/flow/blob/main/templates/styleguides/general.md)
- Keep this skill focused on tool-specific workflows, edge cases, and integration details.Related Skills
flow-memory-keeper
Use at task, phase, flow, sync, archive, finish, revise, or failure checkpoints to keep Flow specs clean, capture learnings and failures, elevate durable patterns, and refine this skill with project-specific nuances
vue
Use when editing Vue projects, .vue files, vue.config.js, Vue 3 components, Composition API, <script setup>, SFC state, deployment workflows, or Vue CI configuration.
vite
Use when editing Vite projects, vite.config.ts, vite.config.js, Vite plugins, HMR, asset bundling, frontend build settings, deployment config, or Litestar/Vite integration.
uvicorn
Use when deploying ASGI apps with uvicorn, editing uvicorn CLI commands, Config or Server usage, workers, reload, event loop selection, SSL, lifespan, logging, or development server behavior.
tracer
Use when tracing execution paths, mapping dependencies, understanding unfamiliar code, following data flow, investigating end-to-end behavior, debugging call chains, or deciding which files to read next.
testing
Use when writing or refactoring tests, editing test_*.py, *.test.ts, *.spec.ts, conftest.py, vitest.config.ts, pytest fixtures, mocks, coverage, async tests, anyio, or test failure debugging.
terraform
Use when creating, adopting, refactoring, or operating Terraform, *.tf files, .terraform.lock.hcl, terragrunt.hcl, root modules, backends, state, workspaces, imports, CI plan/apply, tests, or policy checks.
tanstack
Use when editing TanStack code, @tanstack imports, useQuery, createRouter, React Query, TanStack Router, Table, Form, Store, file-based routing, data fetching, or SPA state management.
tailwind
Use when styling with Tailwind CSS, editing tailwind.config.ts, tailwind.config.js, @tailwind directives, utility classes, responsive layouts, @apply, cn(), @theme config, dark mode, or forms.
svelte
Use when editing Svelte components, .svelte files, svelte.config.js, Svelte 5 runes, $state, $derived, SvelteKit, component state, or migrating away from Svelte 4 patterns.
sqlalchemy
Use when editing SQLAlchemy code, sqlalchemy imports, mapped_column, DeclarativeBase, ORM models, relationships, select() queries, async sessions, engines, events, or migrations.
sphinx
Use when editing Sphinx docs, conf.py, .rst files, docs/source, autodoc, Read the Docs builds, Shibuya or Immaterial themes, Wasm extensions, VHS terminal recordings, or Sphinx CI.