<article class="max-w-4xl mx-auto px-6 py-12">
<header class="mb-12">
<h1 class="text-4xl font-bold mb-4">Microsoft SQL Server</h1>
<p class="text-xl text-muted">
Full MSSQL support with Tiberius driver, including Azure SQL, indexed views, MERGE statements, and SQL Agent jobs.
</p>
</header>
<div class="space-y-12">
<section>
<h2 class="text-2xl font-semibold mb-4">Overview</h2>
<p class="text-muted mb-4">
Prax provides comprehensive Microsoft SQL Server support through the Tiberius async driver.
This includes Azure SQL Database, Azure SQL Managed Instance, and on-premises SQL Server instances.
</p>
<div class="grid md:grid-cols-3 gap-4">
<div class="p-4 rounded-xl bg-surface border border-border">
<div class="text-2xl mb-2">🔒</div>
<h4 class="font-semibold mb-1">Azure Ready</h4>
<p class="text-muted text-sm">Full Azure SQL support with TLS and AAD authentication</p>
</div>
<div class="p-4 rounded-xl bg-surface border border-border">
<div class="text-2xl mb-2">⚡</div>
<h4 class="font-semibold mb-1">MERGE & OUTPUT</h4>
<p class="text-muted text-sm">Native upsert with MERGE and RETURNING via OUTPUT</p>
</div>
<div class="p-4 rounded-xl bg-surface border border-border">
<div class="text-2xl mb-2">📊</div>
<h4 class="font-semibold mb-1">SQL Agent</h4>
<p class="text-muted text-sm">Scheduled jobs via SQL Server Agent integration</p>
</div>
</div>
</section>
<section>
<h2 class="text-2xl font-semibold mb-4">Connection Configuration</h2>
<p class="text-muted mb-4">
Configure your MSSQL connection in <code class="px-2 py-1 bg-surface-elevated rounded">prax.toml</code>.
Supports both SQL authentication and Windows/Azure AD authentication.
</p>
<app-code-block [code]="connectionExample" language="toml" filename="prax.toml" />
</section>
<section>
<h2 class="text-2xl font-semibold mb-4">Schema Definition</h2>
<p class="text-muted mb-4">
Use MSSQL-specific data types with the <code class="px-2 py-1 bg-surface-elevated rounded">@db.</code> attribute.
</p>
<app-code-block [code]="schemaExample" language="prax" filename="prax/schema.prax" />
<div class="mt-4 overflow-x-auto">
<table class="w-full text-sm">
<thead>
<tr class="border-b border-border">
<th class="text-left py-3 px-4 font-semibold">Prax Type</th>
<th class="text-left py-3 px-4 font-semibold">MSSQL Type</th>
<th class="text-left py-3 px-4 font-semibold">Notes</th>
</tr>
</thead>
<tbody class="text-muted">
<tr class="border-b border-border">
<td class="py-3 px-4"><code>String</code></td>
<td class="py-3 px-4"><code>NVARCHAR(255)</code></td>
<td class="py-3 px-4">Use @db.NVarChar(Max) for unlimited</td>
</tr>
<tr class="border-b border-border">
<td class="py-3 px-4"><code>Int</code></td>
<td class="py-3 px-4"><code>INT</code></td>
<td class="py-3 px-4">@db.BigInt for larger values</td>
</tr>
<tr class="border-b border-border">
<td class="py-3 px-4"><code>DateTime</code></td>
<td class="py-3 px-4"><code>DATETIME2</code></td>
<td class="py-3 px-4">Higher precision than DATETIME</td>
</tr>
<tr class="border-b border-border">
<td class="py-3 px-4"><code>Decimal</code></td>
<td class="py-3 px-4"><code>DECIMAL(18,2)</code></td>
<td class="py-3 px-4">Configurable precision/scale</td>
</tr>
<tr class="border-b border-border">
<td class="py-3 px-4"><code>Bytes</code></td>
<td class="py-3 px-4"><code>VARBINARY(MAX)</code></td>
<td class="py-3 px-4">Binary data storage</td>
</tr>
</tbody>
</table>
</div>
</section>
<section>
<h2 class="text-2xl font-semibold mb-4">Indexed Views (Materialized Views)</h2>
<p class="text-muted mb-4">
MSSQL supports indexed views, which are materialized views with a clustered index.
They're automatically updated when base tables change.
</p>
<app-code-block [code]="indexedViewExample" language="prax" filename="prax/schema.prax" />
<div class="mt-4 p-4 rounded-xl bg-info-500/10 border border-info-500/30">
<p class="text-info-400 text-sm">
<strong>Note:</strong> Indexed views require <code>SCHEMABINDING</code> and have restrictions on
the types of queries they can contain. Prax automatically handles these requirements.
</p>
</div>
</section>
<section>
<h2 class="text-2xl font-semibold mb-4">MERGE Statement (Upsert)</h2>
<p class="text-muted mb-4">
MSSQL uses the <code class="px-2 py-1 bg-surface-elevated rounded">MERGE</code> statement for upsert operations,
providing atomic insert-or-update functionality.
</p>
<app-code-block [code]="mergeExample" language="rust" filename="src/main.rs" />
</section>
<section>
<h2 class="text-2xl font-semibold mb-4">OUTPUT Clause (RETURNING)</h2>
<p class="text-muted mb-4">
Get inserted/updated/deleted values back from DML statements using the OUTPUT clause.
</p>
<app-code-block [code]="outputClauseExample" language="rust" filename="src/main.rs" />
</section>
<section>
<h2 class="text-2xl font-semibold mb-4">CROSS APPLY (LATERAL Joins)</h2>
<p class="text-muted mb-4">
MSSQL's CROSS APPLY and OUTER APPLY are equivalent to LATERAL joins in PostgreSQL.
</p>
<app-code-block [code]="crossApplyExample" language="rust" filename="src/main.rs" />
</section>
<section>
<h2 class="text-2xl font-semibold mb-4">Table Hints & Locking</h2>
<p class="text-muted mb-4">
Control locking behavior with MSSQL table hints.
</p>
<app-code-block [code]="lockingExample" language="rust" filename="src/main.rs" />
</section>
<section>
<h2 class="text-2xl font-semibold mb-4">SQL Server Agent Jobs</h2>
<p class="text-muted mb-4">
Define and manage scheduled jobs that run on SQL Server Agent.
</p>
<app-code-block [code]="sqlAgentExample" language="rust" filename="migrations/jobs.rs" />
</section>
<section>
<h2 class="text-2xl font-semibold mb-4">AlwaysOn Availability Groups</h2>
<p class="text-muted mb-4">
Configure read replicas and automatic failover with AlwaysOn.
</p>
<app-code-block [code]="alwaysOnExample" language="rust" filename="src/config.rs" />
</section>
<section>
<h2 class="text-2xl font-semibold mb-4">MSSQL Feature Support</h2>
<div class="overflow-x-auto">
<table class="w-full text-sm">
<thead>
<tr class="border-b border-border">
<th class="text-left py-3 px-4 font-semibold">Feature</th>
<th class="text-left py-3 px-4 font-semibold">Status</th>
<th class="text-left py-3 px-4 font-semibold">Notes</th>
</tr>
</thead>
<tbody class="text-muted">
<tr class="border-b border-border">
<td class="py-3 px-4">Indexed Views</td>
<td class="py-3 px-4"><span class="text-success-400">✅</span></td>
<td class="py-3 px-4">Automatic maintenance</td>
</tr>
<tr class="border-b border-border">
<td class="py-3 px-4">MERGE Statement</td>
<td class="py-3 px-4"><span class="text-success-400">✅</span></td>
<td class="py-3 px-4">Full upsert support</td>
</tr>
<tr class="border-b border-border">
<td class="py-3 px-4">OUTPUT Clause</td>
<td class="py-3 px-4"><span class="text-success-400">✅</span></td>
<td class="py-3 px-4">INSERTED/DELETED access</td>
</tr>
<tr class="border-b border-border">
<td class="py-3 px-4">CROSS/OUTER APPLY</td>
<td class="py-3 px-4"><span class="text-success-400">✅</span></td>
<td class="py-3 px-4">Lateral join equivalent</td>
</tr>
<tr class="border-b border-border">
<td class="py-3 px-4">SQL Agent Jobs</td>
<td class="py-3 px-4"><span class="text-success-400">✅</span></td>
<td class="py-3 px-4">Scheduled tasks</td>
</tr>
<tr class="border-b border-border">
<td class="py-3 px-4">AlwaysOn</td>
<td class="py-3 px-4"><span class="text-success-400">✅</span></td>
<td class="py-3 px-4">HA and read replicas</td>
</tr>
<tr class="border-b border-border">
<td class="py-3 px-4">Row-Level Security</td>
<td class="py-3 px-4"><span class="text-success-400">✅</span></td>
<td class="py-3 px-4">Security predicates</td>
</tr>
<tr class="border-b border-border">
<td class="py-3 px-4">Dynamic Data Masking</td>
<td class="py-3 px-4"><span class="text-success-400">✅</span></td>
<td class="py-3 px-4">Column masking</td>
</tr>
</tbody>
</table>
</div>
</section>
</div>
</article>