Agent skill

SQL Server

Use SQL Server for enterprise relational data storage with advanced features, high availability, and Windows integration.

Stars 10
Forks 1

Install this agent skill to your Project

npx add-skill https://github.com/hivellm/rulebook/tree/main/templates/skills/services/sqlserver

SKILL.md

SQL Server Database Instructions

CRITICAL: Use SQL Server for enterprise relational data storage with advanced features, high availability, and Windows integration.

Core Features

Connection

typescript
// Using mssql (Node.js)
import sql from 'mssql'

const pool = await sql.connect({
  server: process.env.DB_HOST || 'localhost',
  port: parseInt(process.env.DB_PORT || '1433'),
  database: process.env.DB_NAME || 'myapp',
  user: process.env.DB_USER,
  password: process.env.DB_PASSWORD,
  options: {
    encrypt: process.env.NODE_ENV === 'production',
    trustServerCertificate: process.env.NODE_ENV !== 'production',
    enableArithAbort: true,
    connectionTimeout: 30000,
    requestTimeout: 30000,
  },
  pool: {
    max: 10,
    min: 0,
    idleTimeoutMillis: 30000,
  },
})

// Using tedious (lower level)
import { Connection } from 'tedious'

const connection = new Connection({
  server: process.env.DB_HOST || 'localhost',
  authentication: {
    type: 'default',
    options: {
      userName: process.env.DB_USER,
      password: process.env.DB_PASSWORD,
    },
  },
  options: {
    encrypt: true,
    database: process.env.DB_NAME,
    trustServerCertificate: true,
  },
})

Basic Queries

typescript
// SELECT
const result = await pool.request()
  .input('userId', sql.Int, userId)
  .query('SELECT * FROM Users WHERE Id = @userId')
const users = result.recordset

// INSERT
const result = await pool.request()
  .input('name', sql.NVarChar, 'John Doe')
  .input('email', sql.NVarChar, 'john@example.com')
  .query('INSERT INTO Users (Name, Email) OUTPUT INSERTED.* VALUES (@name, @email)')
const newUser = result.recordset[0]

// UPDATE
const result = await pool.request()
  .input('id', sql.Int, userId)
  .input('name', sql.NVarChar, 'Jane Doe')
  .query('UPDATE Users SET Name = @name WHERE Id = @id')

// DELETE
await pool.request()
  .input('id', sql.Int, userId)
  .query('DELETE FROM Users WHERE Id = @id')

Transactions

typescript
const transaction = new sql.Transaction(pool)

try {
  await transaction.begin()
  
  const request = new sql.Request(transaction)
  await request
    .input('userId', sql.Int, userId)
    .input('amount', sql.Decimal(18, 2), 1000)
    .query('INSERT INTO Accounts (UserId, Balance) VALUES (@userId, @amount)')
  
  await request
    .input('accountId', sql.Int, accountId)
    .input('amount', sql.Decimal(18, 2), 1000)
    .query('INSERT INTO Transactions (AccountId, Amount) VALUES (@accountId, @amount)')
  
  await transaction.commit()
} catch (error) {
  await transaction.rollback()
  throw error
}

Advanced Features

typescript
// Stored procedures
const result = await pool.request()
  .input('userId', sql.Int, userId)
  .execute('sp_GetUserDetails')

// JSON operations (SQL Server 2016+)
const result = await pool.request()
  .query(`
    SELECT 
      Id,
      Name,
      JSON_VALUE(Metadata, '$.category') AS Category
    FROM Products
    WHERE JSON_VALUE(Metadata, '$.category') = 'electronics'
  `)

// Full-text search
const result = await pool.request()
  .input('searchTerm', sql.NVarChar, 'search term')
  .query(`
    SELECT * FROM Articles
    WHERE CONTAINS(Content, @searchTerm)
  `)

// Window functions
const result = await pool.request()
  .query(`
    SELECT 
      Name,
      Salary,
      ROW_NUMBER() OVER (PARTITION BY DepartmentId ORDER BY Salary DESC) AS Rank
    FROM Employees
  `)

Common Patterns

Connection Pooling

typescript
let pool: sql.ConnectionPool | null = null

export async function getPool(): Promise<sql.ConnectionPool> {
  if (!pool) {
    pool = await sql.connect({
      // ... config
    })
    
    pool.on('error', (err) => {
      console.error('SQL Server pool error', err)
    })
  }
  return pool
}

// Graceful shutdown
process.on('SIGINT', async () => {
  if (pool) {
    await pool.close()
  }
  process.exit(0)
})

Parameterized Queries

typescript
// Always use parameters to prevent SQL injection
// ❌ WRONG
await pool.request().query(`SELECT * FROM Users WHERE Email = '${email}'`)

// ✅ CORRECT
await pool.request()
  .input('email', sql.NVarChar, email)
  .query('SELECT * FROM Users WHERE Email = @email')

Error Handling

typescript
try {
  const result = await pool.request()
    .input('id', sql.Int, userId)
    .query('SELECT * FROM Users WHERE Id = @id')
  
  if (result.recordset.length === 0) {
    throw new Error('User not found')
  }
  return result.recordset[0]
} catch (error: any) {
  if (error.number === 2627) { // Unique constraint violation
    throw new Error('Duplicate entry')
  }
  if (error.number === 547) { // Foreign key constraint violation
    throw new Error('Referenced record does not exist')
  }
  throw error
}

Best Practices

DO:

  • Use connection pooling (10-20 connections)
  • Always use parameterized queries (@param)
  • Use transactions for multi-step operations
  • Create indexes on frequently queried columns
  • Use appropriate data types (NVarChar for Unicode)
  • Enable encryption in production
  • Use stored procedures for complex logic
  • Monitor connection pool usage
  • Use appropriate timeout values
  • Implement retry logic for transient errors

DON'T:

  • Use string concatenation for queries (SQL injection risk)
  • Create too many connections
  • Skip error handling
  • Ignore connection pool limits
  • Use SELECT * in production
  • Skip indexes on foreign keys
  • Hardcode connection strings
  • Skip encryption in production
  • Ignore query performance
  • Use synchronous operations

Configuration

Environment Variables

bash
DB_HOST=localhost
DB_PORT=1433
DB_NAME=myapp
DB_USER=sa
DB_PASSWORD=securepassword

Docker Compose

yaml
services:
  sqlserver:
    image: mcr.microsoft.com/mssql/server:2022-latest
    ports:
      - "1433:1433"
    environment:
      ACCEPT_EULA: Y
      SA_PASSWORD: securepassword
      MSSQL_PID: Developer
    volumes:
      - sqlserver_data:/var/opt/mssql
    healthcheck:
      test: ["CMD-SHELL", "/opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P securepassword -Q 'SELECT 1' || exit 1"]
      interval: 10s
      timeout: 5s
      retries: 5

volumes:
  sqlserver_data:

Integration with Development

Testing

typescript
// Use test database
const testPool = await sql.connect({
  database: 'myapp_test',
  // ... config
})

// Clean up after tests
afterEach(async () => {
  await testPool.request().query('DELETE FROM Users')
  await testPool.request().query('DELETE FROM Posts')
})

Health Checks

typescript
async function checkDatabaseHealth(): Promise<boolean> {
  try {
    const result = await pool.request().query('SELECT 1 AS Health')
    return result.recordset.length > 0
  } catch {
    return false
  }
}

Didn't find tool you were looking for?

Be as detailed as possible for better results