<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://erikej.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://erikej.github.io/" rel="alternate" type="text/html" /><updated>2026-09-13T11:53:19+00:00</updated><id>https://erikej.github.io/feed.xml</id><title type="html">ErikEJ’s blog</title><subtitle>.NET Data Access and more</subtitle><author><name>ErikEJ</name></author><entry><title type="html">DacDeploySkip update: simpler CI and publish profile support</title><link href="https://erikej.github.io/dotnet/dacfx/sqlserver/sqlpackage/2026/09/13/sqlprojects-dacfx-performance.html" rel="alternate" type="text/html" title="DacDeploySkip update: simpler CI and publish profile support" /><published>2026-09-13T10:45:00+00:00</published><updated>2026-09-13T10:45:00+00:00</updated><id>https://erikej.github.io/dotnet/dacfx/sqlserver/sqlpackage/2026/09/13/sqlprojects-dacfx-performance</id><content type="html" xml:base="https://erikej.github.io/dotnet/dacfx/sqlserver/sqlpackage/2026/09/13/sqlprojects-dacfx-performance.html"><![CDATA[<p>If you deploy <code>.dacpac</code> files frequently, you know how much time is wasted when nothing has actually changed.</p>
<p>That is exactly what <strong>DacDeploySkip</strong> solves: it checks whether the same <code>.dacpac</code> (with the same effective deployment settings) has already been deployed to a target database, and lets you skip unnecessary publishes. See <a href="https://erikej.github.io/dotnet/dacfx/sqlserver/sqlpackage/2026/08/06/faster-dacpac-deployments.html">my overview blog post here</a>.</p>
<h2 id="what-is-new">What is new</h2>
<h3 id="simpler-ci-usage">Simpler CI usage</h3>
<p>Using DacDeploySkip in CI is now simpler, especially in GitHub Actions.</p>
<p>You can use the action directly to:</p>
<ol>
<li>Run <code>check</code> before publishing.</li>
<li>Publish with <code>SqlPackage</code> only if needed.</li>
<li>Run <code>mark</code> after a successful publish.</li>
</ol>
<p>This keeps your workflow small and avoids custom scripting.</p>
<h3 id="publish-profile-support">Publish profile support</h3>
<p>A key improvement is support for including publish profile settings in checksum calculation.</p>
<p>With <code>-profile</code> (or <code>publish-profile</code> in the action), DacDeploySkip includes deployment options and SQLCMD variable values from the <code>.publish.xml</code> file in the checksum. This makes skip decisions more accurate when deployment behavior is controlled by a publish profile.</p>
<p><code>TargetConnectionString</code> and <code>TargetDatabaseName</code> are intentionally excluded.</p>
<h2 id="why-this-matters">Why this matters</h2>
<p>Two deployments of the same <code>.dacpac</code> are not always equivalent when deployment options differ.</p>
<p>By including publish profile options in the checksum, DacDeploySkip can now detect these cases and avoid false &quot;already deployed&quot; decisions.</p>
<h2 id="note-about-sqlpackage">Note about SqlPackage</h2>
<p>Sadly, <strong>FastComparison</strong> which <a href="https://erikej.github.io/dotnet/dacfx/sqlserver/sqlpackage/2026/08/06/faster-dacpac-deployments.html">I blogged about recently</a>, has been (temporarily?) removed from <code>SqlPackage</code>.</p>
<p>Until that returns, you can use DacDeploySkip to improve both the inner developer loop and CI/CD pipeline efficiency.</p>
<h2 id="example">Example</h2>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>dacdeployskip check <span class="s2">"&lt;path to .dacpac&gt;"</span> <span class="s2">"SQL Server connection string"</span> <span class="nt">-profile</span> <span class="s2">"&lt;path to .publish.xml&gt;"</span>
<span class="c"># if exit code is 1 -&gt; run sqlpackage publish</span>
dacdeployskip mark <span class="s2">"&lt;path to .dacpac&gt;"</span> <span class="s2">"SQL Server connection string"</span> <span class="nt">-profile</span> <span class="s2">"&lt;path to .publish.xml&gt;"</span>
</code></pre></div></div>
<h2 id="get-started">Get started</h2>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>dotnet tool <span class="nb">install</span> <span class="nt">-g</span> ErikEJ.DacFX.DacDeploySkip
</code></pre></div></div>
<p>Project: <a href="https://github.com/ErikEJ/DacDeploySkip">github.com/ErikEJ/DacDeploySkip</a></p>]]></content><author><name>ErikEJ</name></author><category term="dotnet" /><category term="dacfx" /><category term="sqlserver" /><category term="sqlpackage" /><summary type="html"><![CDATA[If you deploy .dacpac files frequently, you know how much time is wasted when nothing has actually changed.]]></summary></entry><entry><title type="html">The SSMS extension ecosystem is growing up: list, acquire and maintain extensions with ease</title><link href="https://erikej.github.io/ssms/sqlserver/extensions/2026/09/04/ssms-extension-ecosystem.html" rel="alternate" type="text/html" title="The SSMS extension ecosystem is growing up: list, acquire and maintain extensions with ease" /><published>2026-09-04T18:00:00+00:00</published><updated>2026-09-04T18:00:00+00:00</updated><id>https://erikej.github.io/ssms/sqlserver/extensions/2026/09/04/ssms-extension-ecosystem</id><content type="html" xml:base="https://erikej.github.io/ssms/sqlserver/extensions/2026/09/04/ssms-extension-ecosystem.html"><![CDATA[<p>When SQL Server Management Studio 21 arrived on the Visual Studio 2022 shell, it opened the door for third-party extensions in SSMS for the first time in years. But an extensibility model alone does not make an ecosystem. You also need answers to three simple questions:</p>
<ul>
<li><strong>What extensions exist?</strong></li>
<li><strong>How do I get them?</strong></li>
<li><strong>How do I keep them up to date (and remove them again)?</strong></li>
</ul>
<p>I am happy to say that thanks to great community efforts, all three questions now have good answers. This post is a celebration of the improvements that I and the community have made over the past months — and an invitation for you to join in.</p>
<h2 id="discover-the-ssms-extensions-list">1. Discover: the SSMS Extensions list</h2>
<p>The first challenge was simply knowing what is out there. <a href="https://erikej.github.io/ssms/sqlserver/extensions/2026/05/20/ssms-extensions-sql.html">I briefly blogged about this earlier</a>, and the site has grown nicely since:</p>
<p>👉 <strong><a href="https://erikej.github.io/SsmsExtensions/">SSMS Extensions</a></strong></p>
<p>It is a curated list of extensions and add-ins for SQL Server Management Studio 22, currently listing <strong>45 extensions</strong> — 20 of them free and 14 open source. The list covers everything from Object Explorer enhancements and SQL formatters to performance tuning tools and commercial productivity suites.</p>
<p>The source list was adapted from <a href="https://github.com/brink-daniel/ssms-object-explorer-menu/blob/main/SSMSExtensionList.md">Daniel Brink's SSMS extension catalog</a> — a great example of community collaboration. If you know of an extension that is missing, contributions are very welcome.</p>
<h2 id="acquire-the-ssms-gallery">2. Acquire: the SSMS Gallery</h2>
<p>Knowing an extension exists is one thing — getting hold of it is another. SSMS does not (yet) have an official extension marketplace, so downloads have been scattered across GitHub releases pages, vendor sites and blog posts.</p>
<p>Enter the <strong><a href="https://ssmsgallery.azurewebsites.net/">SSMS Gallery</a></strong> — a free gallery for browsing and downloading free SSMS extensions in one place.</p>
<p>The gallery is based on Mads Kristensen's well-proven <a href="https://github.com/madskristensen/VsixGallery">Open VSIX Gallery</a> code base, adapted for SQL Server Management Studio. It offers:</p>
<ul>
<li><strong>Browse and search</strong> all published extensions with rich descriptions, icons and screenshots.</li>
<li><strong>Direct <code>.vsix</code> downloads</strong> — no hunting through release pages.</li>
<li><strong>ATOM/RSS feeds</strong> for the whole gallery, per author, and per extension — so you can be notified when your favorite extension ships an update.</li>
<li><strong>A simple HTTP publishing API</strong> — publishing is a single <code>POST</code> of your <code>.vsix</code> file, easily automated from GitHub Actions or any other CI system.</li>
</ul>
<p>Several extensions are already published there, including T-SQL Analyzer, SQL Database Project Power Tools, Performance Studio, SQL 4 CDS, SSMS EnvTabs and the SQL Server Compact/SQLite Toolbox.</p>
<h3 id="an-invitation-to-extension-authors">An invitation to extension authors</h3>
<p>If you build an SSMS extension: <strong>please consider publishing it to the SSMS Gallery!</strong> It takes one HTTP call (or one GitHub Actions step) per release, and your users get a stable download location and automatic update notifications for free. Have a look at the &quot;Add Extension&quot; guide on the gallery site to get started — and reach out if you have questions.</p>
<h2 id="maintain-the-ssms-extension-manager">3. Maintain: the SSMS Extension Manager</h2>
<p>The final piece of the puzzle: once you have installed a handful of extensions, how do you keep track of them? Which ones have updates available? How do you cleanly uninstall one?</p>
<p>This is where a great community contribution comes in — <a href="https://github.com/Blake-goofy">Blake-goofy</a>'s <strong><a href="https://github.com/Blake-goofy/ssms-extension-manager">SSMS Extension Manager</a></strong>:</p>
<p>A standalone, open source C# WPF app for managing third-party SSMS 22+ VSIX extensions. With it you can:</p>
<ul>
<li><strong>See all installed</strong> third-party extensions in one view.</li>
<li><strong>Check for updates</strong> and install them with a click.</li>
<li><strong>Browse and install</strong> new extensions directly from the SSMS Gallery feed.</li>
<li><strong>Uninstall</strong> extensions cleanly when you no longer need them.</li>
</ul>
<p>It effectively gives SSMS the &quot;Manage Extensions&quot; experience the community has been asking for. Go grab it from the <a href="https://github.com/Blake-goofy/ssms-extension-manager/releases">releases page</a>, give the repository a ⭐, and file issues with your feedback.</p>
<p><img src="https://raw.githubusercontent.com/ErikEJ/erikej.github.io/master/assets/browseextensions.png" alt="extension manager screenshot" /></p>
<h2 id="the-full-circle">The full circle</h2>
<p>Put the three together and the workflow looks like this:</p>
<ol>
<li><strong>Discover</strong> an extension on the <a href="https://erikej.github.io/SsmsExtensions/">SSMS Extensions list</a>.</li>
<li><strong>Download</strong> it from the <a href="https://ssmsgallery.azurewebsites.net/">SSMS Gallery</a> (or install it directly via the Extension Manager).</li>
<li><strong>Maintain</strong> it with the <a href="https://github.com/Blake-goofy/ssms-extension-manager">SSMS Extension Manager</a> — update notifications, one-click updates and clean uninstalls.</li>
</ol>
<p>None of this would have happened without the community: Daniel Brink's original extension catalog, Mads Kristensen's Open VSIX Gallery code base, Blake-goofy's Extension Manager, and every author who has published an extension so far. Thank you all! 🎉</p>
<p>If you are an SSMS extension author — or thinking about becoming one — now is a great time to jump in. Publish to the gallery, get listed, and let your users keep themselves up to date.</p>
<p>Comments and feedback are welcome, as always.</p>]]></content><author><name>ErikEJ</name></author><category term="ssms" /><category term="sqlserver" /><category term="extensions" /><summary type="html"><![CDATA[When SQL Server Management Studio 21 arrived on the Visual Studio 2022 shell, it opened the door for third-party extensions in SSMS for the first time in years. But an extensibility model alone does not make an ecosystem. You also need answers to three simple questions:]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://raw.githubusercontent.com/ErikEJ/erikej.github.io/master/assets/browseextensions.png" /><media:content medium="image" url="https://raw.githubusercontent.com/ErikEJ/erikej.github.io/master/assets/browseextensions.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Launch: T-SQL Analyzer live analysis now in VS Code</title><link href="https://erikej.github.io/sql/dacfx/vscode/2026/08/12/tsql-analyzer-vscode.html" rel="alternate" type="text/html" title="Launch: T-SQL Analyzer live analysis now in VS Code" /><published>2026-08-12T18:00:00+00:00</published><updated>2026-08-12T18:00:00+00:00</updated><id>https://erikej.github.io/sql/dacfx/vscode/2026/08/12/tsql-analyzer-vscode</id><content type="html" xml:base="https://erikej.github.io/sql/dacfx/vscode/2026/08/12/tsql-analyzer-vscode.html"><![CDATA[<p>I'm excited to announce that the T-SQL Analyzer is now available for Visual
Studio Code! You can now catch T-SQL mistakes <strong>as you type</strong>, directly in the
VS Code editor — no build step required.</p>
<h2 id="background">Background</h2>
<p>I maintain a collection of over 140 <a href="https://github.com/ErikEJ/SqlServer.Rules">open source</a>
static code analysis rules based on the DacFX API, covering T-SQL best practices
for design, naming, and performance.</p>
<p>I previously blogged about the launch of the T-SQL Analyzer extension for
<a href="https://erikej.github.io/sql/dacfx/visualstudio/2025/08/25/dacfx-visx-rules.html">Visual Studio</a>,
and more recently about the
<a href="https://erikej.github.io/sql/dacfx/visualstudio/ssms/2026/06/21/analysis-ssms-visualstudio.html">significant update that brought live analysis to SSMS and Visual Studio</a>.</p>
<p>This post covers the newest addition to the family: a dedicated Visual Studio
Code extension, so you get the same real-time feedback on your SQL scripts no
matter which editor you prefer.</p>
<h2 id="whats-new">What's new</h2>
<h3 id="live-analysis-in-vs-code">Live analysis in VS Code</h3>
<p>The extension analyzes your <code>.sql</code> files in real time and highlights design,
naming, and performance issues right in the editor. Problems appear as squiggles
while you edit, just like compiler errors.</p>
<p><img src="https://raw.githubusercontent.com/ErikEJ/SqlServer.Rules/master/vscode-extension/images/screenshot.png" alt="diagnostics screenshot" /></p>
<p>Key features:</p>
<ul>
<li><strong>Live squiggles</strong> — problems appear while you edit, just like compiler errors</li>
<li><strong>140+ built-in rules</strong> — covering design best practices, naming conventions,
and performance pitfalls</li>
<li><strong>Hover for details</strong> — hover over any squiggle to see the rule id, a plain
English description, and a link to the full documentation</li>
<li><strong>Zero configuration</strong> — works out of the box with sensible defaults</li>
<li><strong>Customizable</strong> — disable individual rules, promote warnings to errors, or
target a specific SQL Server version</li>
<li><strong>Status bar indicator</strong> — shows when analysis is running</li>
</ul>
<h3 id="any-sql-script-analyzed">Any SQL script analyzed</h3>
<p>Just like the SSMS and Visual Studio extensions, the VS Code extension analyzes
any SQL script you have open — whether it is a stored procedure, a query, a
migration script, a one-off data fix, or anything else. If you're writing SQL,
you get feedback.</p>
<h3 id="customizing-rules">Customizing rules</h3>
<p>All rules are <strong>enabled</strong> by default. You can fine-tune them in <strong>Settings</strong>
using a rules expression:</p>
<table>
<thead>
<tr>
<th>What you want</th>
<th>Expression</th>
</tr>
</thead>
<tbody>
<tr>
<td>Disable a single rule</td>
<td><code>-SqlServer.Rules.SRD0004</code></td>
</tr>
<tr>
<td>Disable all naming rules</td>
<td><code>-SqlServer.Rules.SRN*</code></td>
</tr>
<tr>
<td>Promote a rule to an error</td>
<td><code>+!SqlServer.Rules.SRN0005</code></td>
</tr>
<tr>
<td>Combine several</td>
<td><code>-SqlServer.Rules.SRD0004;+!SqlServer.Rules.SRN0005</code></td>
</tr>
</tbody>
</table>
<p>Browse the full rule catalogue at
<a href="https://github.com/ErikEJ/SqlServer.Rules/tree/master/docs">github.com/ErikEJ/SqlServer.Rules/docs</a>.</p>
<h3 id="settings">Settings</h3>
<table>
<thead>
<tr>
<th>Setting</th>
<th>Default</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>tsqlAnalyzer.enable</code></td>
<td><code>true</code></td>
<td>Turn live analysis on or off.</td>
</tr>
<tr>
<td><code>tsqlAnalyzer.rules</code></td>
<td><em>(all enabled)</em></td>
<td>Rules expression (see above).</td>
</tr>
<tr>
<td><code>tsqlAnalyzer.sqlVersion</code></td>
<td><code>Sql170</code></td>
<td>Target SQL Server version (<code>Sql160</code>, <code>Sql170</code>, <code>SqlAzure</code>, <code>SqlDwUnified</code>, …).</td>
</tr>
<tr>
<td><code>tsqlAnalyzer.debounceMs</code></td>
<td><code>400</code></td>
<td>Milliseconds to wait after the last keystroke before analyzing.</td>
</tr>
<tr>
<td><code>tsqlAnalyzer.additionalAnalyzers</code></td>
<td></td>
<td>Extra analyzer <code>.dll</code> paths to load (advanced).</td>
</tr>
<tr>
<td><code>tsqlAnalyzer.serverPath</code></td>
<td></td>
<td>Path to a local analyzer build (advanced — leave empty to use the published package).</td>
</tr>
</tbody>
</table>
<h3 id="commands">Commands</h3>
<p>Open the Command Palette (<code>Ctrl+Shift+P</code> / <code>Cmd+Shift+P</code>) and type
<strong>T-SQL Analyzer</strong>:</p>
<ul>
<li><strong>T-SQL Analyzer: Analyze Active File</strong> — run analysis on demand.</li>
<li><strong>T-SQL Analyzer: Restart Analysis Server</strong> — restart the background analyzer
process (useful after updating settings).</li>
</ul>
<h2 id="getting-started">Getting started</h2>
<ol>
<li>Install the <a href="https://dotnet.microsoft.com/download/dotnet/10.0">.NET 10 SDK</a>
(or later).</li>
<li>Install the extension from the VS Code Marketplace.</li>
<li>Open any <code>.sql</code> file — analysis starts automatically.</li>
</ol>
<p>That's it. The analyzer tooling is downloaded automatically on first use; there
is nothing else to install.</p>
<h2 id="summary">Summary</h2>
<table>
<thead>
<tr>
<th>Editor</th>
<th>Live analysis</th>
</tr>
</thead>
<tbody>
<tr>
<td>Visual Studio</td>
<td>✓</td>
</tr>
<tr>
<td>SQL Server Management Studio 22</td>
<td>✓</td>
</tr>
<tr>
<td>Visual Studio Code</td>
<td>✓ (new!)</td>
</tr>
</tbody>
</table>
<h2 id="feedback-and-contributions">Feedback and contributions</h2>
<p>Should you encounter bugs or have feature requests, head over to the
<a href="https://github.com/ErikEJ/SqlServer.Rules">GitHub repository</a> to open an issue if one
doesn't already exist.</p>
<p>If you enjoy using the extension, please give it a ★★★★★ rating on the VS Code
Marketplace.</p>
<p>Another way to help out is to <a href="https://github.com/sponsors/ErikEJ">sponsor me on GitHub</a>.</p>]]></content><author><name>ErikEJ</name></author><category term="sql" /><category term="dacfx" /><category term="vscode" /><summary type="html"><![CDATA[I'm excited to announce that the T-SQL Analyzer is now available for Visual Studio Code! You can now catch T-SQL mistakes as you type, directly in the VS Code editor — no build step required.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://raw.githubusercontent.com/ErikEJ/SqlServer.Rules/master/vscode-extension/images/screenshot.png" /><media:content medium="image" url="https://raw.githubusercontent.com/ErikEJ/SqlServer.Rules/master/vscode-extension/images/screenshot.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">From 20+ seconds to 2 - faster SQL Database Project .dacpac deployments are finally here (preview)</title><link href="https://erikej.github.io/dotnet/dacfx/sqlserver/sqlpackage/2026/08/06/faster-dacpac-deployments.html" rel="alternate" type="text/html" title="From 20+ seconds to 2 - faster SQL Database Project .dacpac deployments are finally here (preview)" /><published>2026-08-06T18:00:00+00:00</published><updated>2026-08-06T18:00:00+00:00</updated><id>https://erikej.github.io/dotnet/dacfx/sqlserver/sqlpackage/2026/08/06/faster-dacpac-deployments</id><content type="html" xml:base="https://erikej.github.io/dotnet/dacfx/sqlserver/sqlpackage/2026/08/06/faster-dacpac-deployments.html"><![CDATA[<p>If you have ever deployed a SQL Database Project (<code>.sqlproj</code>) or a <code>.dacpac</code> with
<code>SqlPackage</code>, you know the drill: you kick off a publish against an empty or
near-empty database, grab a coffee, and wait. Even for tiny schemas, every single
publish reliably took <strong>20+ seconds</strong> before anything actually happened on the server.</p>
<p>That fixed &quot;startup tax&quot; has been one of the most requested pain points for years -
and I am thrilled to say it is finally being addressed. With the
<a href="https://github.com/microsoft/DacFx/blob/main/release-notes/Microsoft.SqlPackage/170.5/170.5.60-preview.md">DacFx 170.5.60-preview</a> release, a
warm publish can now complete in around <strong>2 seconds</strong>. That is a 10x improvement on
the part of the deployment that used to feel like pure overhead.</p>
<blockquote>
<p>I actually attempted <a href="https://github.com/ErikEJ/DacDeploySkip">something similar</a> a while ago, and will share my experience from that attempt with the DacFX team.</p>
</blockquote>
<h2 id="why-was-it-always-20-seconds">Why was it always 20 seconds?</h2>
<p>Every publish begins by loading and validating the model contained in the <code>.dacpac</code>,
building an in-memory representation of your schema, and comparing it against the
target, requiring large metadata queries against the target database.
Historically a large chunk of that work was repeated on every run, regardless
of whether anything had actually changed. For small projects the model work
completely dominated the wall-clock time - hence the constant ~20 second floor.</p>
<p>The work latest sqlpackage and DacFX preview removes that
redundant work, so repeated publishes of the same <code>.dacpac</code> no longer pay the full
model cost each time.</p>
<h2 id="how-to-try-it-out">How to try it out</h2>
<p>The feature is in <strong>preview</strong>, so you need the latest preview build of <code>SqlPackage</code>.</p>
<ol>
<li>
<p>Make sure you have the <a href="https://dotnet.microsoft.com/download">.NET SDK</a> installed.</p>
</li>
<li>
<p>Install (or update to) the latest preview of the <code>SqlPackage</code> global tool:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>dotnet tool <span class="nb">install</span> <span class="nt">-g</span> microsoft.sqlpackage <span class="nt">--prerelease</span>
</code></pre></div></div>
</li>
<li>
<p>Confirm you are on the preview build (170.5.60.2 or higher):</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sqlpackage /version
</code></pre></div></div>
</li>
<li>
<p>Publish with the new additional parameters and enjoy the speed</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sqlpackage /Action:Publish ^
    /SourceFile:MyDatabase.dacpac ^
    /TargetServerName:localhost ^
    /TargetDatabaseName:MyDatabase ^
    /p:LogDeployment<span class="o">=</span><span class="nb">true</span> ^
    /p:EnableFastComparison<span class="o">=</span><span class="nb">true</span>
</code></pre></div></div>
</li>
</ol>
<p>Run the same publish a second time to see the warm-path improvement in action.</p>
<p>You will see this logged to the console when fast deployment kicks in:</p>
<p><code>Fast comparison match found, source model checksum and deployment options match last logged deployment. Database reverse engineering and deployment plan generation is skipped. Disable fast comparison to run a full model comparison.</code></p>
<blockquote>
<p>Notice that this feature assumes no drift (ouside schema changes) between deployments. In other words, it assumes that the .dacpac owns the database schema.</p>
</blockquote>
<h2 id="under-the-hood">Under the hood</h2>
<p><img src="https://erikej.github.io/assets/fastdeploy.png" alt="" /></p>
<p>The key change is that the model checksum and additional metadata is now cached in a system table in the target database,
so that subsequent publishes can skip the model reverse engineer and model build steps, resulting in significantly faster deployments.</p>
<p>The system table to store the &quot;vectors&quot; of the currently deployed package has the folloiwng structure:</p>
<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">CREATE</span> <span class="k">TABLE</span> <span class="p">[</span><span class="n">dbo</span><span class="p">].[</span><span class="n">__DacFxDeploymentHistory</span><span class="p">](</span>
   <span class="p">[</span><span class="n">deployment_id</span><span class="p">]</span> <span class="p">[</span><span class="nb">int</span><span class="p">]</span> <span class="k">IDENTITY</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">)</span> <span class="k">NOT</span> <span class="k">NULL</span><span class="p">,</span>
   <span class="p">[</span><span class="n">dacpac_name</span><span class="p">]</span> <span class="p">[</span><span class="nb">varchar</span><span class="p">](</span><span class="mi">256</span><span class="p">)</span> <span class="k">NOT</span> <span class="k">NULL</span><span class="p">,</span>
   <span class="p">[</span><span class="n">project_id</span><span class="p">]</span> <span class="p">[</span><span class="n">uniqueidentifier</span><span class="p">]</span> <span class="k">NOT</span> <span class="k">NULL</span><span class="p">,</span>
   <span class="p">[</span><span class="n">dac_version</span><span class="p">]</span> <span class="p">[</span><span class="n">nvarchar</span><span class="p">](</span><span class="mi">64</span><span class="p">)</span> <span class="k">NOT</span> <span class="k">NULL</span><span class="p">,</span>
   <span class="p">[</span><span class="n">deployment_options</span><span class="p">]</span> <span class="p">[</span><span class="n">xml</span><span class="p">]</span> <span class="k">NULL</span><span class="p">,</span>
   <span class="p">[</span><span class="n">model_checksum</span><span class="p">]</span> <span class="p">[</span><span class="nb">varbinary</span><span class="p">](</span><span class="mi">32</span><span class="p">)</span> <span class="k">NOT</span> <span class="k">NULL</span><span class="p">,</span>
   <span class="p">[</span><span class="n">date_created</span><span class="p">]</span> <span class="p">[</span><span class="n">datetime2</span><span class="p">](</span><span class="mi">7</span><span class="p">)</span> <span class="k">NOT</span> <span class="k">NULL</span><span class="p">,</span>
   <span class="p">[</span><span class="n">created_by</span><span class="p">]</span> <span class="p">[</span><span class="n">sysname</span><span class="p">]</span> <span class="k">NOT</span> <span class="k">NULL</span><span class="p">,</span>
   <span class="p">[</span><span class="n">description</span><span class="p">]</span> <span class="p">[</span><span class="n">nvarchar</span><span class="p">](</span><span class="mi">4000</span><span class="p">)</span> <span class="k">NULL</span><span class="p">,</span>
 <span class="k">CONSTRAINT</span> <span class="p">[</span><span class="n">PK___DacFxDeploymentHistory</span><span class="p">]</span> <span class="k">PRIMARY</span> <span class="k">KEY</span> <span class="n">CLUSTERED</span> 
<span class="p">(</span>
  <span class="p">[</span><span class="n">deployment_id</span><span class="p">]</span> <span class="k">ASC</span>
<span class="p">)</span><span class="k">WITH</span> <span class="p">(</span><span class="n">PAD_INDEX</span> <span class="o">=</span> <span class="k">OFF</span><span class="p">,</span> <span class="n">STATISTICS_NORECOMPUTE</span> <span class="o">=</span> <span class="k">OFF</span><span class="p">,</span> <span class="n">IGNORE_DUP_KEY</span> <span class="o">=</span> <span class="k">OFF</span><span class="p">,</span> <span class="n">ALLOW_ROW_LOCKS</span> <span class="o">=</span> <span class="k">ON</span><span class="p">,</span> <span class="n">ALLOW_PAGE_LOCKS</span> <span class="o">=</span> <span class="k">ON</span><span class="p">,</span> <span class="n">OPTIMIZE_FOR_SEQUENTIAL_KEY</span> <span class="o">=</span> <span class="k">OFF</span><span class="p">)</span> <span class="k">ON</span> <span class="p">[</span><span class="k">PRIMARY</span><span class="p">]</span>
<span class="p">)</span> <span class="k">ON</span> <span class="p">[</span><span class="k">PRIMARY</span><span class="p">]</span> <span class="n">TEXTIMAGE_ON</span> <span class="p">[</span><span class="k">PRIMARY</span><span class="p">]</span>
<span class="k">GO</span>

<span class="k">ALTER</span> <span class="k">TABLE</span> <span class="p">[</span><span class="n">dbo</span><span class="p">].[</span><span class="n">__DacFxDeploymentHistory</span><span class="p">]</span> <span class="k">ADD</span>  <span class="k">DEFAULT</span> <span class="p">(</span><span class="n">sysutcdatetime</span><span class="p">())</span> <span class="k">FOR</span> <span class="p">[</span><span class="n">date_created</span><span class="p">]</span>
<span class="k">GO</span>

<span class="k">ALTER</span> <span class="k">TABLE</span> <span class="p">[</span><span class="n">dbo</span><span class="p">].[</span><span class="n">__DacFxDeploymentHistory</span><span class="p">]</span> <span class="k">ADD</span>  <span class="k">DEFAULT</span> <span class="p">(</span><span class="n">original_login</span><span class="p">())</span> <span class="k">FOR</span> <span class="p">[</span><span class="n">created_by</span><span class="p">]</span>
<span class="k">GO</span>
</code></pre></div></div>
<p>The <code>/p:LogDeployment=true</code> parameter is required to enable the creation of this table and the logging of the model checksum and deployment options etc.</p>
<p>You can monitor the contents of this table to see the last deployed model checksum and deployment options. You can also use this to verify that the fast comparison would work as expected before your turn on <code>/p:EnableFastComparison=true</code>.</p>
<p>Any changes to the schema will update the stored model checksum, so that subsequent publishes can detect that a full model comparison is required.</p>
<p>Likewise any changes to the <a href="https://learn.microsoft.com/sql/tools/sqlpackage/sqlpackage-publish#properties-specific-to-the-publish-action">deployment options</a> will also update the stored deployment options, so that subsequent publishes can detect that a full model comparison is required.</p>
<p>Based on this query executed by sqlpackage, you can see that the decision to use skip full deployment is based on entries scoped to the current <code>ProjectGuid</code> of the .dacpac:</p>
<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">exec</span> <span class="n">sp_executesql</span> <span class="n">N</span><span class="s1">'SELECT TOP 1 
      [deployment_id], [dacpac_name], [project_id], [dac_version],
      [deployment_options], [model_checksum],
      [date_created], [created_by], [description]
FROM [dbo].[__DacFxDeploymentHistory] WITH (NOLOCK)
WHERE [project_id] = @projectId
ORDER BY [date_created] DESC'</span><span class="p">,</span><span class="n">N</span><span class="s1">'@projectId uniqueidentifier'</span><span class="p">,</span><span class="o">@</span><span class="n">projectId</span><span class="o">=</span><span class="s1">'726D17BA-DCCA-4607-8C1F-3A68523C7112'</span>
</code></pre></div></div>
<p><code>/p:EnableFastComparison=true</code> requires <code>/p:LogDeployment=true</code> in order to work. And if the outcome of the fast comparision is a match, then deployment is skipped.</p>
<p>I tried changing a post deployment script, and the next publish incorrectly skipped the model comparison,
so it seems that only schema and deployment options changes are detected.</p>
<p>This is a known limitation of the current implementation. I have <a href="https://github.com/microsoft/DacFx/issues/824">filed a bug for this</a>.</p>
<h2 id="one-caveat-the-missing-projectguid">One caveat: the missing ProjectGuid</h2>
<p>While trying this out, you may hit an issue where the speed-up does not kick in
because the <code>.dacpac</code> is missing a <code>ProjectGuid</code>, which is used to identify the
project across publishes. This is being tracked in
<a href="https://github.com/microsoft/DacFx/issues/824">microsoft/DacFx#824</a>. If you do not
see the improved timings, this is the most likely culprit - keep an eye on the issue
for the recommended workaround and follow-up fixes.</p>
<h2 id="wrapping-up">Wrapping up</h2>
<p>This is a preview, so expect a few rough edges, but it is a fantastic step forward
for anyone doing frequent, iterative database deployments - especially in inner-loop
development and CI where those seconds add up fast.</p>
<p>Give it a try, and please report any feedback on the
<a href="https://github.com/microsoft/DacFx/issues">DacFx repo</a>. Huge thanks to the DacFx
team for tackling this long-standing request!</p>
<p>Happy (fast) deploying!</p>]]></content><author><name>ErikEJ</name></author><category term="dotnet" /><category term="dacfx" /><category term="sqlserver" /><category term="sqlpackage" /><summary type="html"><![CDATA[If you have ever deployed a SQL Database Project (.sqlproj) or a .dacpac with SqlPackage, you know the drill: you kick off a publish against an empty or near-empty database, grab a coffee, and wait. Even for tiny schemas, every single publish reliably took 20+ seconds before anything actually happened on the server.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://raw.githubusercontent.com/ErikEJ/erikej.github.io/master/assets/fastdeploy.png" /><media:content medium="image" url="https://raw.githubusercontent.com/ErikEJ/erikej.github.io/master/assets/fastdeploy.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Updated: T-SQL Analyzer live analysis now in SSMS and Visual Studio</title><link href="https://erikej.github.io/sql/dacfx/visualstudio/ssms/2026/06/21/analysis-ssms-visualstudio.html" rel="alternate" type="text/html" title="Updated: T-SQL Analyzer live analysis now in SSMS and Visual Studio" /><published>2026-06-21T17:28:49+00:00</published><updated>2026-06-21T17:28:49+00:00</updated><id>https://erikej.github.io/sql/dacfx/visualstudio/ssms/2026/06/21/analysis-ssms-visualstudio</id><content type="html" xml:base="https://erikej.github.io/sql/dacfx/visualstudio/ssms/2026/06/21/analysis-ssms-visualstudio.html"><![CDATA[<p>The T-SQL Analyzer extensions for Visual Studio and SQL Server Management Studio have been significantly updated. Here's what's new.</p>
<h2 id="background">Background</h2>
<p>I maintain a collection of over 140 <a href="https://github.com/ErikEJ/SqlServer.Rules">open source</a> static code analysis rules based on the DacFX API, covering T-SQL best practices for design, naming, and performance.</p>
<p>I previously <a href="https://erikej.github.io/sql/dacfx/visualstudio/2025/08/25/dacfx-visx-rules.html">blogged about</a> the launch of the T-SQL Analyzer extension for Visual Studio, which provided live analysis of SQL scripts as you author them.</p>
<p>This post covers a significant update to both the Visual Studio and the new SQL Server Management Studio extension.</p>
<h2 id="whats-new">What's new</h2>
<h3 id="now-available-in-sql-server-management-studio-22">Now available in SQL Server Management Studio 22</h3>
<p>The live analysis experience is no longer limited to Visual Studio — it is now also available in <strong>SQL Server Management Studio 22</strong> (SSMS). You get the same real-time feedback on your SQL scripts as you type, directly in the SSMS query editor.</p>
<p>The SSMS extension is available in the new <a href="https://ssmsgallery.azurewebsites.net/extension/TSqlAnalyzerSsms.f1322c34-dfaa-4842-8933-b439626da91d">SSMS VSIX Gallery</a>.</p>
<p><img src="https://raw.githubusercontent.com/ErikEJ/SqlServer.Rules/master/tools/SqlAnalyzerSsms/sql-analysis.png" alt="" /></p>
<h3 id="analysis-of-any-sql-script--not-just-create-statements">Analysis of any SQL script — not just CREATE statements</h3>
<p>Previously, live analysis only triggered on SQL scripts that contained <code>CREATE</code> statements — the kind typically found inside SQL database projects. The extension has now been revamped to analyze <strong>any SQL script</strong> you have open in the editor, whether it is a stored procedure, a query, a migration script, a one-off data fix, or anything else. If you're writing SQL, you now get feedback.</p>
<blockquote>
<p>If you encounter any issues with this new feature, please create an issue in the <a href="https://github.com/ErikEJ/SqlServer.Rules">GitHub repo</a></p>
</blockquote>
<h3 id="configure-via-tools--options">Configure via Tools / Options</h3>
<p>Both extensions now expose settings under <strong>Tools → Options</strong> → *<strong>T-SQL Analyzer</strong> in Visual Studio and SSMS, so you can customize behavior without editing project files.</p>
<table>
<thead>
<tr>
<th>Setting</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Run static T-SQL analysis</strong></td>
<td>Enable or disable live analysis entirely</td>
</tr>
<tr>
<td><strong>SQL engine version</strong></td>
<td>Set the SQL Server dialect used for analysis (SQL Server 2005 through SQL Server 2025, Azure SQL Database, Synapse, Fabric, and more)</td>
</tr>
<tr>
<td><strong>Rule exceptions</strong></td>
<td>Set a rules expression to suppress or enforce specific rules when no SQL project configuration is present (e.g. <code>+!SqlServer.Rules.SRD0006;-SqlServer.Rules.SRN*</code>)</td>
</tr>
</tbody>
</table>
<p>These options apply globally when a script is <strong>not part of a SQL database project</strong>. When a project is involved, the extension defers to the project configuration (see below).</p>
<h3 id="project-settings-are-still-respected">Project settings are still respected</h3>
<p>If your SQL script is part of a SQL database project (based on <a href="https://github.com/rr-wfm/MSBuild.Sdk.SqlProj">MSBuild.Sdk.SqlProj</a>, <a href="https://github.com/microsoft/DacFx/tree/main/src/Microsoft.Build.Sql">Microsoft.Build.Sql</a>, or a classic <code>.sqlproj</code>), the extension continues to respect the project's own configuration:</p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;Project</span> <span class="na">Sdk=</span><span class="s">"MSBuild.Sdk.SqlProj/3.2.0"</span><span class="nt">&gt;</span>
  <span class="nt">&lt;PropertyGroup&gt;</span>
    <span class="nt">&lt;TargetFramework&gt;</span>net8.0<span class="nt">&lt;/TargetFramework&gt;</span>
    <span class="nt">&lt;SqlServerVersion&gt;</span>Sql170<span class="nt">&lt;/SqlServerVersion&gt;</span>
    <span class="nt">&lt;RunSqlCodeAnalysis&gt;</span>True<span class="nt">&lt;/RunSqlCodeAnalysis&gt;</span>
    <span class="nt">&lt;CodeAnalysisRules&gt;</span>-SqlServer.Rules.SRD0006<span class="nt">&lt;/CodeAnalysisRules&gt;</span>
    <span class="c">&lt;!-- This property supports wildcard rule filters --&gt;</span>
    <span class="c">&lt;!-- and overrides 'CodeAnalysisRules' above if present --&gt;</span>
    <span class="nt">&lt;AnalyzerCodeAnalysisRules&gt;</span>-SqlServer.Rules.SRD0006;-Microsoft.*<span class="nt">&lt;/AnalyzerCodeAnalysisRules&gt;</span>
  <span class="nt">&lt;/PropertyGroup&gt;</span>
<span class="nt">&lt;/Project&gt;</span>
</code></pre></div></div>
<p>This means if analysis is disabled in the project, or if you have suppressed specific rules via <code>CodeAnalysisRules</code> or <code>AnalyzerCodeAnalysisRules</code>, the live extension honours those settings. The global Tools/Options settings only apply when no project configuration is found.</p>
<h2 id="installation">Installation</h2>
<h3 id="visual-studio">Visual Studio</h3>
<p>Download the extension from the <a href="https://marketplace.visualstudio.com/items?itemName=ErikEJ.TSqlAnalyzer">Visual Studio Marketplace</a>.</p>
<ul>
<li><strong>Visual Studio 2026 and later</strong>: No separate installation required — the extension uses the <code>dnx</code> command to run the T-SQL Analyzer CLI as a NuGet package automatically.</li>
<li><strong>Visual Studio 2022</strong>: Install the latest version of the CLI tool first:</li>
</ul>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>dotnet tool <span class="nb">install</span> <span class="nt">-g</span> ErikEJ.DacFX.TSQLAnalyzer.CLI
</code></pre></div></div>
<h3 id="ssms">SSMS</h3>
<p>Download the extension from the new <a href="https://ssmsgallery.azurewebsites.net/extension/TSqlAnalyzerSsms.f1322c34-dfaa-4842-8933-b439626da91d">SSMS VSIX Gallery</a>.</p>
<p>The extension automatically uses the <code>dnx</code> command to run the T-SQL Analyzer CLI tool. No separate installation is needed, but the <a href="https://dotnet.microsoft.com/en-us/download">.NET 10 SDK</a> is required (automatically installed with the Database DevOps workload in SSMS).</p>
<h2 id="summary">Summary</h2>
<table>
<thead>
<tr>
<th>Feature</th>
<th>Before</th>
<th>Now</th>
</tr>
</thead>
<tbody>
<tr>
<td>Visual Studio support</td>
<td>✓</td>
<td>✓</td>
</tr>
<tr>
<td>SSMS support</td>
<td>✗</td>
<td>✓</td>
</tr>
<tr>
<td>Any SQL script analyzed</td>
<td>✗ (CREATE only)</td>
<td>✓</td>
</tr>
<tr>
<td>Tools/Options settings</td>
<td>✗</td>
<td>✓</td>
</tr>
<tr>
<td>Respect SQL project settings</td>
<td>✓</td>
<td>✓</td>
</tr>
</tbody>
</table>
<h2 id="feedback-and-contributions">Feedback and contributions</h2>
<p>Should you encounter bugs or have feature requests, head over to the <a href="https://github.com/ErikEJ/SqlServer.Rules">GitHub repo</a> to open an issue if one doesn't already exist.</p>
<p>If you enjoy using the extensions, please give them a ★★★★★ rating on the <a href="https://marketplace.visualstudio.com/items?itemName=ErikEJ.TSqlAnalyzer">Visual Studio Marketplace</a>.</p>
<p>Another way to help out is to <a href="https://github.com/sponsors/ErikEJ">sponsor me on GitHub</a>.</p>]]></content><author><name>ErikEJ</name></author><category term="sql" /><category term="dacfx" /><category term="visualstudio" /><category term="ssms" /><summary type="html"><![CDATA[The T-SQL Analyzer extensions for Visual Studio and SQL Server Management Studio have been significantly updated. Here's what's new.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://raw.githubusercontent.com/ErikEJ/SqlServer.Rules/master/tools/SqlAnalyzerVsix/Images/editor.png" /><media:content medium="image" url="https://raw.githubusercontent.com/ErikEJ/SqlServer.Rules/master/tools/SqlAnalyzerVsix/Images/editor.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Deterministic SQL Bad Practice Detection in SSMS 22.7 with T-SQL Analyzer MCP Server and Copilot</title><link href="https://erikej.github.io/sql/ssms/mcp/dacfx/2026/06/10/ssms-mcp-sql-analyzer.html" rel="alternate" type="text/html" title="Deterministic SQL Bad Practice Detection in SSMS 22.7 with T-SQL Analyzer MCP Server and Copilot" /><published>2026-06-10T17:28:49+00:00</published><updated>2026-06-10T17:28:49+00:00</updated><id>https://erikej.github.io/sql/ssms/mcp/dacfx/2026/06/10/ssms-mcp-sql-analyzer</id><content type="html" xml:base="https://erikej.github.io/sql/ssms/mcp/dacfx/2026/06/10/ssms-mcp-sql-analyzer.html"><![CDATA[<p>SQL Server Management Studio (SSMS) 22.7 introduces support for agents and MCP (Model Context Protocol) Servers, opening new possibilities for integrating third-party analysis tools directly into your development workflow. In this post, I'll show you how to use the T-SQL Analyzer MCP Server to deterministically detect bad practices and anti-patterns in your SQL Server scripts right within SSMS.</p>
<blockquote>
<p>Note that everything demonstrated in this blog post is already available in Visual Studio and VS Code.</p>
</blockquote>
<p><img src="https://erikej.github.io/assets/ssmscopilot.png" alt="" /></p>
<h2 id="requirements">Requirements</h2>
<ul>
<li><strong>.NET 10.0 runtime</strong> (minimum requirement for MCP Server mode)</li>
<li><strong>SSMS 22.7</strong> or later</li>
</ul>
<h2 id="background-why-this-matters">Background: Why This Matters</h2>
<p>As a SQL developer, you want to catch design issues, performance anti-patterns, and security vulnerabilities early—ideally before code reaches production. The T-SQL Analyzer tool includes 140+ rules covering design, naming, and performance concerns. With SSMS 22.7's MCP Server support, you can now leverage this analysis directly in your IDE, with the added benefit of being able to rely on .NET 10's latest performance improvements.</p>
<h2 id="whats-new-in-ssms-227">What's New in SSMS 22.7?</h2>
<p>SSMS 22.7 adds native Agent support that can communicate with MCP Servers. This means tools like T-SQL Analyzer can now:</p>
<ul>
<li>Analyze SQL scripts deterministically using pre-defined rules</li>
<li>Provide actionable feedback within the editor context</li>
<li>Integrate with your existing SQL development workflow</li>
</ul>
<h2 id="setting-up-the-t-sql-analyzer-mcp-server">Setting Up the T-SQL Analyzer MCP Server</h2>
<h3 id="step-1-verify-net-100-installation">Step 1: Verify .NET 10.0 Installation</h3>
<p>Ensure you have .NET 10.0 runtime installed:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>dotnet <span class="nt">--version</span>
</code></pre></div></div>
<p>If you don't have .NET 10.0, download it from <a href="https://dot.net">dot.net</a>.</p>
<h3 id="step-2-configure-ssms-227-mcp-server">Step 2: Configure SSMS 22.7 MCP Server</h3>
<p>Create or update your SSMS MCP configuration file at:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>C:<span class="se">\U</span>sers<span class="se">\&lt;</span>username&gt;<span class="se">\.</span>mcp.json
</code></pre></div></div>
<p>Replace <code>&lt;username&gt;</code> with your Windows username. The recommended configuration uses the .NET 10 <code>dnx</code> launcher to automatically restore and invoke the T-SQL Analyzer package:</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
    </span><span class="nl">"servers"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
        </span><span class="nl">"tsqlanalyzer"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
            </span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"stdio"</span><span class="p">,</span><span class="w">
            </span><span class="nl">"command"</span><span class="p">:</span><span class="w"> </span><span class="s2">"dnx"</span><span class="p">,</span><span class="w">
            </span><span class="nl">"args"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
                </span><span class="s2">"ErikEJ.DacFX.TSQLAnalyzer.Cli"</span><span class="p">,</span><span class="w">
                </span><span class="s2">"--yes"</span><span class="p">,</span><span class="w">
                </span><span class="s2">"--"</span><span class="p">,</span><span class="w">
                </span><span class="s2">"-mcp"</span><span class="w">
            </span><span class="p">]</span><span class="w">
        </span><span class="p">}</span><span class="w">
    </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>
<p>This configuration:</p>
<ul>
<li>Uses <code>dnx</code> to download and run the latest T-SQL Analyzer package from NuGet</li>
<li><code>--yes</code> automatically restores the package if needed</li>
<li><code>--</code> separates package arguments from MCP arguments</li>
<li><code>-mcp</code> tells the analyzer to launch in MCP Server mode</li>
</ul>
<h3 id="step-3-enable-the-mcp-server-in-ssms">Step 3: Enable the MCP Server in SSMS</h3>
<ol>
<li>Open SSMS 22.7</li>
<li>Open GitHub Copilot, select Agent mode and enable the <code>find_sql_script_problems</code> in the <code>TSQLAnalyzerMCP</code> local MCP server.</li>
</ol>
<p><img src="https://erikej.github.io/assets/ssmsagent.png" alt="" /></p>
<h2 id="how-it-works-deterministic-analysis">How It Works: Deterministic Analysis</h2>
<p>The MCP Server exposes a single analysis tool: <code>find_sql_script_problems</code>. This tool:</p>
<ol>
<li><strong>Accepts</strong> the text content of your SQL CREATE script</li>
<li><strong>Parses</strong> the script using DacFx's T-SQL parser</li>
<li><strong>Evaluates</strong> it against 140+ built-in rules (design, naming, performance, security)</li>
<li><strong>Returns</strong> a structured list of issues with line numbers, severity, and descriptions</li>
</ol>
<h3 id="example-detecting-a-potential-sql-injection">Example: Detecting a Potential SQL Injection</h3>
<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">CREATE</span> <span class="k">PROCEDURE</span> <span class="p">[</span><span class="n">dbo</span><span class="p">].[</span><span class="n">GetUserData</span><span class="p">]</span>
    <span class="o">@</span><span class="n">userId</span> <span class="nb">VARCHAR</span><span class="p">(</span><span class="mi">255</span><span class="p">)</span>
<span class="k">AS</span>
<span class="k">BEGIN</span>
    <span class="k">DECLARE</span> <span class="o">@</span><span class="k">sql</span> <span class="n">NVARCHAR</span><span class="p">(</span><span class="mi">1024</span><span class="p">);</span>
    <span class="k">SELECT</span> <span class="o">@</span><span class="k">sql</span> <span class="o">=</span> <span class="n">CONCAT</span><span class="p">(</span><span class="n">N</span><span class="s1">'SELECT * FROM Users WHERE Id = </span><span class="se">''</span><span class="s1">'</span><span class="p">,</span> <span class="o">@</span><span class="n">userId</span><span class="p">,</span> <span class="n">N</span><span class="s1">'</span><span class="se">''</span><span class="s1">'</span><span class="p">);</span>
    <span class="k">EXEC</span> <span class="p">[</span><span class="n">sys</span><span class="p">].[</span><span class="n">sp_executesql</span><span class="p">]</span> <span class="o">@</span><span class="n">stmt</span> <span class="o">=</span> <span class="o">@</span><span class="k">sql</span><span class="p">;</span>
<span class="k">END</span><span class="p">;</span>
</code></pre></div></div>
<p>When you analyze this procedure in SSMS:</p>
<ol>
<li><strong>Right-click</strong> on the query editor or use the SSMS Agent</li>
<li><strong>Select</strong> &quot;Analyze with T-SQL Analyzer&quot;</li>
<li>The MCP Server immediately detects:
<ul>
<li><strong>SRD0096</strong> (Design): Potential SQL injection issue (tainted variable in dynamic SQL)</li>
<li>Any other applicable rule violations</li>
</ul>
</li>
<li>GitHub Copilot provides a summary of the findings, and may offer to fix them.</li>
</ol>
<p>The analysis is <strong>deterministic</strong>—the same script always produces the same results based on the rule set.</p>
<h2 id="supported-rule-categories">Supported Rule Categories</h2>
<p>The analyzer covers three main categories:</p>
<h3 id="design-rules-srd">Design Rules (SRD*)</h3>
<ul>
<li>Hardcoded credentials</li>
<li>Unnamed primary keys</li>
<li>SQL injection vulnerabilities</li>
<li>Missing schema qualifiers</li>
<li>And more...</li>
</ul>
<h3 id="naming-rules-srn">Naming Rules (SRN*)</h3>
<ul>
<li>Single-character aliases and variables</li>
<li>Non-standard naming patterns</li>
<li>Case sensitivity issues</li>
</ul>
<h3 id="performance-rules-srp">Performance Rules (SRP*)</h3>
<ul>
<li>Implicit range windows in window functions</li>
<li>Deprecated functions (CAST, CONVERT misuse)</li>
<li>Cross-server joins</li>
<li>Missing indexes and query store settings</li>
<li>And more...</li>
</ul>
<h2 id="key-advantages-in-ssms-227">Key Advantages in SSMS 22.7</h2>
<ol>
<li><strong>In-Context Feedback</strong>: Analyze without leaving the editor</li>
<li><strong>Deterministic Results</strong>: Same analysis every time; no LLM variance or hallucinations</li>
<li><strong>Rule-Based</strong>: Transparent, predictable logic based on SQL Server best practices</li>
<li><strong>Quick Feedback Loop</strong>: Immediate results as you work</li>
</ol>
<h2 id="example-workflow">Example Workflow</h2>
<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>1. Open your stored procedure in SSMS
   ↓
2. Use SSMS Copilot Agent to invoke the MCP Server
   ↓
3. T-SQL Analyzer scans the script against 140+ rules
   ↓
4. Results appear in SSMS—each issue shows line number, rule ID, and description
   ↓
5. Fix the issues or add IGNORE comments for false positives
   ↓
6. Re-analyze to confirm
</code></pre></div></div>
<h2 id="comparison-t-sql-analyzer-mcp-server-vs-command-line">Comparison: T-SQL Analyzer MCP Server vs. Command Line</h2>
<table>
<thead>
<tr>
<th>Feature</th>
<th>SSMS MCP Server</th>
<th>Command-Line CLI</th>
</tr>
</thead>
<tbody>
<tr>
<td>In-IDE analysis</td>
<td>✓</td>
<td>✗</td>
</tr>
<tr>
<td>Batch file processing</td>
<td>✗</td>
<td>✓</td>
</tr>
<tr>
<td>CI/CD Integration</td>
<td>✗</td>
<td>✓</td>
</tr>
<tr>
<td>Interactive feedback</td>
<td>✓</td>
<td>✗</td>
</tr>
<tr>
<td>Deterministic results</td>
<td>✓</td>
<td>✓</td>
</tr>
</tbody>
</table>
<h2 id="getting-started">Getting Started</h2>
<ol>
<li><strong>Verify .NET 10.0</strong>: Run <code>dotnet --version</code> to confirm .NET 10.0 is installed</li>
<li><strong>Create configuration file</strong>: Create or edit <code>C:\Users\&lt;username&gt;\.mcp.json</code> (replace <code>&lt;username&gt;</code> with your Windows username)</li>
<li><strong>Add the MCP server entry</strong> to your configuration file (see Step 2 above)</li>
<li><strong>Enable the server in SSMS</strong>: Enable the MCP server in the GitHub Copilot window</li>
<li><strong>Analyze</strong>: Ask Copilot to use the MCP Server</li>
<li><strong>Fix</strong>: Ask Copilot to address the issues</li>
</ol>
<h2 id="why-net-100">Why .NET 10.0?</h2>
<p>The T-SQL Analyzer MCP Server requires .NET 10.0 to take advantage of the latest performance improvements and framework enhancements. The <code>dnx</code> package runner automatically handles fetching and executing the latest version of the tool, ensuring you always have access to the newest rules and optimizations without manual updates.</p>
<h2 id="next-steps">Next Steps</h2>
<ul>
<li>Check out the <a href="https://github.com/ErikEJ/SqlServer.Rules/tree/master/docs">documentation</a> for detailed rule descriptions</li>
<li>Review the <a href="https://github.com/ErikEJ/SqlServer.Rules">GitHub repository</a> for source code and community contributions</li>
<li>Follow the blog for updates on new rules and SSMS features</li>
</ul>
<h2 id="call-to-action">Call to Action</h2>
<p>The combination of SSMS 22.7's MCP Server support and the T-SQL Analyzer brings professional-grade SQL static analysis to your fingertips. Try it out and let me know how it improves your SQL development workflow!</p>
<hr />
<ul>
<li><a href="https://github.com/erikej">GitHub</a></li>
<li><a href="https://www.x.com/erikej">X</a></li>
</ul>
<p><em>Follow the blog for more posts on SQL Server, static analysis, and developer tools.</em></p>]]></content><author><name>ErikEJ</name></author><category term="sql" /><category term="ssms" /><category term="mcp" /><category term="dacfx" /><summary type="html"><![CDATA[SQL Server Management Studio (SSMS) 22.7 introduces support for agents and MCP (Model Context Protocol) Servers, opening new possibilities for integrating third-party analysis tools directly into your development workflow. In this post, I'll show you how to use the T-SQL Analyzer MCP Server to deterministically detect bad practices and anti-patterns in your SQL Server scripts right within SSMS.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://raw.githubusercontent.com/ErikEJ/erikej.github.io/master/assets/ssmsagent.png" /><media:content medium="image" url="https://raw.githubusercontent.com/ErikEJ/erikej.github.io/master/assets/ssmsagent.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Instantly deploy T-SQL programmability changes on save in SQL Projects with SQL Project Power Tools</title><link href="https://erikej.github.io/dotnet/dacfx/sqlserver/visualstudio/ssms/2026/06/01/sqlprojects-dacfx.html" rel="alternate" type="text/html" title="Instantly deploy T-SQL programmability changes on save in SQL Projects with SQL Project Power Tools" /><published>2026-06-01T11:00:00+00:00</published><updated>2026-06-01T11:00:00+00:00</updated><id>https://erikej.github.io/dotnet/dacfx/sqlserver/visualstudio/ssms/2026/06/01/sqlprojects-dacfx</id><content type="html" xml:base="https://erikej.github.io/dotnet/dacfx/sqlserver/visualstudio/ssms/2026/06/01/sqlprojects-dacfx.html"><![CDATA[<p>In this blog post I will describe a new feature in <a href="https://marketplace.visualstudio.com/items?itemName=ErikEJ.SqlProjectPowerTools">SQL Project Power Tools</a>: <strong>Publish programmability objects on save</strong>. This feature lets you instantly deploy stored procedures, views, functions, and triggers to your development database the moment you save the corresponding <code>.sql</code> file in Visual Studio — no full dacpac deployment required.</p>
<h2 id="the-problem-slow-feedback-loop-for-programmability-objects">The problem: slow feedback loop for programmability objects</h2>
<p>SQL Database Projects are a great way to manage your database schema in source control. The normal development workflow is:</p>
<ol>
<li>Edit your <code>.sql</code> files in Visual Studio</li>
<li>Build the project to produce a <code>.dacpac</code> file</li>
<li>Deploy the <code>.dacpac</code> to your development database (via dacpac publish or schema compare)</li>
<li>Test your changes</li>
</ol>
<p>This workflow works well for schema objects like <strong>tables</strong> and <strong>indexes</strong>, where dacpac deployment is essential — it handles complex operations like renaming columns, adding constraints, and managing data migrations safely. You really do need the full deployment pipeline for those.</p>
<p>However, for <strong>programmability objects</strong> — stored procedures, views, functions, and triggers — the situation is different. These objects can be replaced atomically using SQL Server's <code>CREATE OR ALTER</code> statement, which has been supported since SQL Server 2016. There is no need to build and deploy a full <code>.dacpac</code> just to update a stored procedure body.</p>
<p>Unfortunately, SQL Database Projects (and the underlying DacFx tooling) do not allow you to selectively deploy a single file. Every change still requires building the full <code>.dacpac</code> and running a deployment, even if you only changed a single stored procedure. This has been raised as a <a href="https://github.com/microsoft/DacFx/issues/753">feature request with the DacFx team</a>, but in the meantime SQL Project Power Tools provides a practical workaround.</p>
<h2 id="the-solution-publish-programmability-objects-on-save">The solution: Publish programmability objects on save</h2>
<p>The new <strong>Publish programmability objects on save</strong> feature detects when you save a <code>.sql</code> file that contains a supported programmability object and immediately executes a <code>CREATE OR ALTER</code> version of that script against your development database. The status bar shows a confirmation when the publish completes, or an error message if something goes wrong.</p>
<blockquote>
<p><strong>Important distinction:</strong> This feature only works for <em>programmability objects</em> — stored procedures, views, functions, and triggers. Schema objects such as tables, indexes, and constraints are deliberately excluded. Changing a table definition has data implications that require the full DACpac deployment pipeline to handle safely.</p>
</blockquote>
<h2 id="how-it-works">How it works</h2>
<p>When a <code>.sql</code> file is saved in Visual Studio:</p>
<ol>
<li>The extension checks whether the file belongs to a SQL Database Project.</li>
<li>It looks for an <code>.env</code> file in the project directory containing an <code>AutoPublish</code> connection string.</li>
<li>If found, it parses the script using the T-SQL parser and verifies it contains only supported statements: <code>CREATE PROCEDURE</code>, <code>CREATE VIEW</code>, <code>CREATE FUNCTION</code>, or <code>CREATE TRIGGER</code> (and <code>SET</code> options).</li>
<li>Any <code>CREATE</code> statement that is not already <code>CREATE OR ALTER</code> is automatically rewritten to use <code>CREATE OR ALTER</code>.</li>
<li>The rewritten script is executed against the database specified in the connection string.</li>
<li>The Visual Studio status bar shows <code>Publish completed: &lt;filename&gt;</code> on success, or <code>Publish failed: &lt;filename&gt;</code> on failure.</li>
</ol>
<p>Files that contain table definitions, <code>ALTER TABLE</code>, <code>INSERT</code>, <code>DROP</code>, or any other statements that are not programmability object definitions are silently skipped — the feature does nothing for those files.</p>
<h2 id="setting-up-the-feature">Setting up the feature</h2>
<h3 id="step-1-enable-the-option">Step 1: Enable the option</h3>
<p>The feature is off by default. To turn it on, open <strong>Tools &gt; Options &gt; SQL Server Tools &gt; SQL Project Power Tools</strong> in Visual Studio and check the <strong>Enable auto publish on save</strong> option.</p>
<h3 id="step-2-add-the-connection-string">Step 2: Add the connection string</h3>
<p>Create a file named <code>.env</code> in the root of your SQL Database Project directory (the same folder as your <code>.sqlproj</code> or <code>.csproj</code> file). Add a line in the following format:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">AutoPublish</span><span class="o">=</span><span class="nv">Server</span><span class="o">=</span>localhost<span class="p">;</span><span class="nv">Database</span><span class="o">=</span>MyDevDatabase<span class="p">;</span>Integrated <span class="nv">Security</span><span class="o">=</span><span class="nb">true</span><span class="p">;</span><span class="nv">TrustServerCertificate</span><span class="o">=</span><span class="nb">true</span>
</code></pre></div></div>
<p>You can use any valid SQL Server connection string. The key must be <code>AutoPublish</code> (case-insensitive).</p>
<blockquote>
<p><strong>Security tip:</strong> The <code>.env</code> file contains a connection string, so make sure to add it to <code>.gitignore</code> to avoid committing credentials to source control.</p>
</blockquote>
<h3 id="step-3-save-a-programmability-object">Step 3: Save a programmability object</h3>
<p>Open a <code>.sql</code> file in your project that contains a <code>CREATE PROCEDURE</code>, <code>CREATE VIEW</code>, <code>CREATE FUNCTION</code>, or <code>CREATE TRIGGER</code> statement, make a change, and save. The extension will automatically rewrite the statement to <code>CREATE OR ALTER</code> and execute it against the development database. Watch the status bar at the bottom of Visual Studio for the completion message.</p>
<h2 id="example">Example</h2>
<p>Suppose you have a stored procedure in your project at <code>dbo/Stored Procedures/GetCustomerById.sql</code>:</p>
<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">CREATE</span> <span class="k">PROCEDURE</span> <span class="p">[</span><span class="n">dbo</span><span class="p">].[</span><span class="n">GetCustomerById</span><span class="p">]</span>
    <span class="o">@</span><span class="n">Id</span> <span class="nb">INT</span>
<span class="k">AS</span>
<span class="k">BEGIN</span>
    <span class="k">SET</span> <span class="n">NOCOUNT</span> <span class="k">ON</span><span class="p">;</span>
    <span class="k">SELECT</span> <span class="n">Id</span><span class="p">,</span> <span class="n">Name</span><span class="p">,</span> <span class="n">Email</span>
    <span class="k">FROM</span> <span class="n">dbo</span><span class="p">.</span><span class="n">Customers</span>
    <span class="k">WHERE</span> <span class="n">Id</span> <span class="o">=</span> <span class="o">@</span><span class="n">Id</span><span class="p">;</span>
<span class="k">END</span>
</code></pre></div></div>
<p>When you save this file with the feature enabled and a valid <code>.env</code> file present, the extension will execute the following against your development database:</p>
<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">CREATE</span> <span class="k">OR</span> <span class="k">ALTER</span> <span class="k">PROCEDURE</span> <span class="p">[</span><span class="n">dbo</span><span class="p">].[</span><span class="n">GetCustomerById</span><span class="p">]</span>
    <span class="o">@</span><span class="n">Id</span> <span class="nb">INT</span>
<span class="k">AS</span>
<span class="k">BEGIN</span>
    <span class="k">SET</span> <span class="n">NOCOUNT</span> <span class="k">ON</span><span class="p">;</span>
    <span class="k">SELECT</span> <span class="n">Id</span><span class="p">,</span> <span class="n">Name</span><span class="p">,</span> <span class="n">Email</span>
    <span class="k">FROM</span> <span class="n">dbo</span><span class="p">.</span><span class="n">Customers</span>
    <span class="k">WHERE</span> <span class="n">Id</span> <span class="o">=</span> <span class="o">@</span><span class="n">Id</span><span class="p">;</span>
<span class="k">END</span>
</code></pre></div></div>
<p>The stored procedure is updated immediately, without a full build and deploy cycle.</p>
<h2 id="other-features-in-sql-project-power-tools">Other features in SQL Project Power Tools</h2>
<p>SQL Project Power Tools includes many other features to improve the SQL Database Project developer experience:</p>
<ul>
<li><strong>Templates</strong> — Project and item templates for creating new SDK-style SQL Database Projects and common object types from File &gt; New &gt; Project and Add &gt; New Item.</li>
<li><strong>Import database</strong> — Import the full schema of an existing database into your project, with configurable file layout (flat, by object type, by schema, or by schema and object type).</li>
<li><strong>Schema compare</strong> — Visually compare your database project with a live database and apply changes in either direction.</li>
<li><strong>Analyze</strong> — Run static code analysis on your project and view a detailed report of issues.</li>
<li><strong>Manage code analysis rules</strong> — Enable or disable individual static analysis rules and set their severity directly from a visual dialog, for SDK-style projects.</li>
<li><strong>Create Mermaid E/R diagram</strong> — Generate an Entity-Relationship diagram of selected tables for documentation.</li>
<li><strong>.dacpac Solution Explorer node</strong> — Browse the contents of a built <code>.dacpac</code> file directly from Solution Explorer.</li>
<li><strong>Script Table Data</strong> — Generate <code>INSERT</code> statements for table data to use as seed data in post-deployment scripts, based on <a href="https://github.com/dnlnln/generate-sql-merge">generate-sql-merge</a>.</li>
<li><strong>Add pre- and post-deployment scripts</strong> — Quickly add new pre- and post-deployment scripts to your project from the context menu.</li>
<li><strong>Scaffold SQL MCP Server (preview)</strong> — Generate a <a href="https://github.com/ErikEJ/SqlProjectPowerTools/blob/main/docs/dab-mcp-readme.md">SQL MCP Server</a> configuration file based on your database project schema.</li>
</ul>
<p>A <a href="https://github.com/ErikEJ/SqlProjectPowerTools/blob/main/docs/getting-started.md">getting started guide</a> covers all of these features in more detail.</p>
<h2 id="getting-the-extension">Getting the extension</h2>
<h3 id="visual-studio">Visual Studio</h3>
<p>Install <strong>SQL Project Power Tools</strong> from the <a href="https://marketplace.visualstudio.com/items?itemName=ErikEJ.SqlProjectPowerTools">Visual Studio Marketplace</a>, or search for it directly in Visual Studio via <strong>Extensions &gt; Manage Extensions</strong>.</p>
<h3 id="ssms">SSMS</h3>
<p>Install <strong>SQL Project Power Tools</strong> from the new <a href="https://ssmsgallery.azurewebsites.net/extension/SqlProjectsPowerTools.SSMS.D7DABDC8-FE46-4DA4-BED8-2EAF1A2A578D">SSMS Gallery</a>.</p>
<h2 id="contribute">Contribute</h2>
<p>The source code is open source and available on <a href="https://github.com/ErikEJ/SqlProjectPowerTools">GitHub</a>. If you find the extension useful, a ★★★★★ rating on the Marketplace is always appreciated. Bug reports and feature requests are welcome on the <a href="https://github.com/ErikEJ/SqlProjectPowerTools/issues">GitHub issue tracker</a>.</p>]]></content><author><name>ErikEJ</name></author><category term="dotnet" /><category term="dacfx" /><category term="sqlserver" /><category term="visualstudio" /><category term="ssms" /><summary type="html"><![CDATA[In this blog post I will describe a new feature in SQL Project Power Tools: Publish programmability objects on save. This feature lets you instantly deploy stored procedures, views, functions, and triggers to your development database the moment you save the corresponding .sql file in Visual Studio — no full dacpac deployment required.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://raw.githubusercontent.com/ErikEJ/SQLProjectPowerTools/main/img/menu.png" /><media:content medium="image" url="https://raw.githubusercontent.com/ErikEJ/SQLProjectPowerTools/main/img/menu.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">SqlServer.Rules 5.0.0 is out 🎉</title><link href="https://erikej.github.io/sqlserver/dacfx/2026/05/21/sql-dacfx-rules.html" rel="alternate" type="text/html" title="SqlServer.Rules 5.0.0 is out 🎉" /><published>2026-05-21T17:28:49+00:00</published><updated>2026-05-21T17:28:49+00:00</updated><id>https://erikej.github.io/sqlserver/dacfx/2026/05/21/sql-dacfx-rules</id><content type="html" xml:base="https://erikej.github.io/sqlserver/dacfx/2026/05/21/sql-dacfx-rules.html"><![CDATA[<p><code>SqlServer.Rules</code> <strong>v5.0.0</strong> is <a href="https://github.com/ErikEJ/SqlServer.Rules/releases/tag/v5.0.0">now available</a></p>
<p>SqlServer.Rules is an open-source static code analysis library and toolset for SQL Server database projects, command line, and Visual Studio, that helps teams catch design flaws, naming inconsistencies, performance anti-patterns, and risky T-SQL constructs early — during development and build time instead of in production.</p>
<p>The value is straightforward: it shifts SQL quality checks left, gives fast and repeatable feedback in CI/CD and local workflows, and helps improve reliability, maintainability, and performance of database code with clear, actionable rule-based guidance.</p>
<p>This major release expands rule coverage significantly and continues consolidation around the <code>SqlServer.Rules</code> codebase and tooling.</p>
<h2 id="highlights">Highlights</h2>
<ul>
<li>Large set of new and migrated design and performance rules</li>
<li>New SQL project/database option checks</li>
<li>Completed migration from legacy TSQLSmells packaging</li>
<li>Tooling and repository improvements</li>
</ul>
<h2 id="new-and-ported-rules-with-docs-links">New and Ported Rules (with docs links)</h2>
<h3 id="design-rules">Design rules</h3>
<ul>
<li><a href="https://github.com/ErikEJ/SqlServer.Rules/blob/master/docs/Design/SRD0078.md"><code>SRD0078</code> Single-character aliases are poor practice</a></li>
<li><a href="https://github.com/ErikEJ/SqlServer.Rules/blob/master/docs/Design/SRD0079.md"><code>SRD0079</code> Single-character variables are poor practice</a></li>
<li><a href="https://github.com/ErikEJ/SqlServer.Rules/blob/master/docs/Design/SRD0080.md"><code>SRD0080</code> TOP expression should use parentheses</a></li>
<li><a href="https://github.com/ErikEJ/SqlServer.Rules/blob/master/docs/Design/SRD0081.md"><code>SRD0081</code> <code>TOP(100) PERCENT</code> is ignored by optimizer</a></li>
<li><a href="https://github.com/ErikEJ/SqlServer.Rules/blob/master/docs/Design/SRD0082.md"><code>SRD0082</code> Avoid changing <code>DATEFORMAT</code></a></li>
<li><a href="https://github.com/ErikEJ/SqlServer.Rules/blob/master/docs/Design/SRD0083.md"><code>SRD0083</code> Avoid changing <code>DATEFIRST</code></a></li>
<li><a href="https://github.com/ErikEJ/SqlServer.Rules/blob/master/docs/Design/SRD0084.md"><code>SRD0084</code> <code>CONCAT_NULL_YIELDS_NULL</code> must be <code>ON</code></a></li>
<li><a href="https://github.com/ErikEJ/SqlServer.Rules/blob/master/docs/Design/SRD0085.md"><code>SRD0085</code> <code>ANSI_NULLS</code> should be <code>ON</code></a></li>
<li><a href="https://github.com/ErikEJ/SqlServer.Rules/blob/master/docs/Design/SRD0086.md"><code>SRD0086</code> <code>ANSI_PADDING</code> should be <code>ON</code></a></li>
<li><a href="https://github.com/ErikEJ/SqlServer.Rules/blob/master/docs/Design/SRD0087.md"><code>SRD0087</code> <code>ANSI_WARNINGS</code> should be <code>ON</code></a></li>
<li><a href="https://github.com/ErikEJ/SqlServer.Rules/blob/master/docs/Design/SRD0088.md"><code>SRD0088</code> <code>NUMERIC_ROUNDABORT</code> should be <code>OFF</code></a></li>
<li><a href="https://github.com/ErikEJ/SqlServer.Rules/blob/master/docs/Design/SRD0089.md"><code>SRD0089</code> <code>QUOTED_IDENTIFIER</code> should be <code>ON</code></a></li>
<li><a href="https://github.com/ErikEJ/SqlServer.Rules/blob/master/docs/Design/SRD0090.md"><code>SRD0090</code> <code>SET FORCEPLAN</code> should be <code>OFF</code></a></li>
<li><a href="https://github.com/ErikEJ/SqlServer.Rules/blob/master/docs/Design/SRD0091.md"><code>SRD0091</code> Avoid <code>ORDER BY</code> in derived tables for final ordering</a></li>
<li><a href="https://github.com/ErikEJ/SqlServer.Rules/blob/master/docs/Design/SRD0092.md"><code>SRD0092</code> Avoid named primary key constraints on temp tables</a></li>
<li><a href="https://github.com/ErikEJ/SqlServer.Rules/blob/master/docs/Design/SRD0093.md"><code>SRD0093</code> Do not name default constraints on temporary tables</a></li>
<li><a href="https://github.com/ErikEJ/SqlServer.Rules/blob/master/docs/Design/SRD0094.md"><code>SRD0094</code> Avoid named foreign keys on temporary tables</a></li>
<li><a href="https://github.com/ErikEJ/SqlServer.Rules/blob/master/docs/Design/SRD0095.md"><code>SRD0095</code> Named check constraints on temp tables</a></li>
<li><a href="https://github.com/ErikEJ/SqlServer.Rules/blob/master/docs/Design/SRD0096.md"><code>SRD0096</code> Potential SQL injection issue</a></li>
</ul>
<h3 id="performance-rules">Performance rules</h3>
<ul>
<li><a href="https://github.com/ErikEJ/SqlServer.Rules/blob/master/docs/Performance/SRP0026.md"><code>SRP0026</code> Avoid cross-server joins</a></li>
<li><a href="https://github.com/ErikEJ/SqlServer.Rules/blob/master/docs/Performance/SRP0027.md"><code>SRP0027</code> Avoid explicit conversion of columnar data</a></li>
<li><a href="https://github.com/ErikEJ/SqlServer.Rules/blob/master/docs/Performance/SRP0028.md"><code>SRP0028</code> Explicit <code>RANGE</code> window frame</a></li>
<li><a href="https://github.com/ErikEJ/SqlServer.Rules/blob/master/docs/Performance/SRP0029.md"><code>SRP0029</code> Implicit <code>RANGE</code> window frame</a></li>
<li><a href="https://github.com/ErikEJ/SqlServer.Rules/blob/master/docs/Performance/SRP0030.md"><code>SRP0030</code> Specify <code>FAST_FORWARD</code> for cursors</a></li>
</ul>
<h3 id="sql-projectdatabase-option-rules">SQL project/database option rules</h3>
<ul>
<li><a href="https://github.com/ErikEJ/SqlServer.Rules/blob/master/docs/Design/SRD0700.md"><code>SRD0700</code> Database <code>PAGE_VERIFY</code> option is not <code>CHECKSUM</code></a></li>
<li><a href="https://github.com/ErikEJ/SqlServer.Rules/blob/master/docs/Design/SRD0701.md"><code>SRD0701</code> Database <code>QUERY_STORE</code> option is not <code>READ_WRITE</code></a></li>
<li><a href="https://github.com/ErikEJ/SqlServer.Rules/blob/master/docs/Design/SRD0703.md"><code>SRD0703</code> Database <code>QUERY_STORE_CAPTURE_MODE</code> option is not <code>AUTO</code></a></li>
<li><a href="https://github.com/ErikEJ/SqlServer.Rules/blob/master/docs/Design/SRD0704.md"><code>SRD0704</code> Database <code>TARGET_RECOVERY_TIME</code> option is not set</a></li>
<li><a href="https://github.com/ErikEJ/SqlServer.Rules/blob/master/docs/Design/SRD0705.md"><code>SRD0705</code> Database <code>AUTO_CLOSE</code> option is not <code>OFF</code></a></li>
<li><a href="https://github.com/ErikEJ/SqlServer.Rules/blob/master/docs/Design/SRD0706.md"><code>SRD0706</code> Database <code>AUTO_SHRINK</code> option is <code>ON</code></a></li>
</ul>
<h2 id="tooling-and-cleanup">Tooling and cleanup</h2>
<ul>
<li>Documentation generation moved to a separate tool</li>
<li>Solution updates (including <code>.slnx</code>)</li>
<li>Legacy TSQLSmells package/sign/test removal</li>
</ul>
<h2 id="upgrade">Upgrade</h2>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;PackageReference</span> <span class="na">Include=</span><span class="s">"ErikEJ.DacFX.SqlServer.Rules"</span> <span class="na">Version=</span><span class="s">"5.0.0"</span><span class="nt">&gt;</span>
  <span class="nt">&lt;PrivateAssets&gt;</span>all<span class="nt">&lt;/PrivateAssets&gt;</span>
<span class="nt">&lt;/PackageReference&gt;</span>
</code></pre></div></div>
<h2 id="full-changelog">Full changelog</h2>
<ul>
<li><a href="https://github.com/ErikEJ/SqlServer.Rules/releases/tag/v5.0.0">Release notes</a></li>
</ul>
<p>Thanks to all contributors and everyone using and testing <code>SqlServer.Rules</code>.</p>]]></content><author><name>ErikEJ</name></author><category term="sqlserver" /><category term="dacfx" /><summary type="html"><![CDATA[SqlServer.Rules v5.0.0 is now available]]></summary></entry><entry><title type="html">Launching the SSMS Extension Gallery</title><link href="https://erikej.github.io/ssms/sqlserver/extensions/2026/05/20/ssms-extensions-sql.html" rel="alternate" type="text/html" title="Launching the SSMS Extension Gallery" /><published>2026-05-20T11:28:49+00:00</published><updated>2026-05-20T11:28:49+00:00</updated><id>https://erikej.github.io/ssms/sqlserver/extensions/2026/05/20/ssms-extensions-sql</id><content type="html" xml:base="https://erikej.github.io/ssms/sqlserver/extensions/2026/05/20/ssms-extensions-sql.html"><![CDATA[<p>I’m excited to announce the launch of the <strong>SSMS Extension Gallery</strong>:</p>
<p>👉 <a href="https://erikej.github.io/SsmsExtensions/">Find it here</a></p>
<p>This new page gives SQL Server developers and DBAs a quick overview of tools that can improve day-to-day work in SQL Server Management Studio 22.</p>
<p>The goal with this launch is simple: make it easier to discover both free and commercial SSMS extensions in one place.</p>
<p>I got inspired to build this by the blog post <a href="https://www.brentozar.com/archive/2026/05/announcing-the-ssms-statisticsparser-extension/">from Brent Ozar here</a>.</p>
<p>If you build or maintain an SSMS 22 extension and want it included, please <a href="https://github.com/ErikEJ/SsmsExtensions/issues">open an issue or pull request</a>.</p>]]></content><author><name>ErikEJ</name></author><category term="ssms" /><category term="sqlserver" /><category term="extensions" /><summary type="html"><![CDATA[I’m excited to announce the launch of the SSMS Extension Gallery:]]></summary></entry><entry><title type="html">Visual Schema Compare for SDK Style SQL Database Projects in Visual Studio and SSMS</title><link href="https://erikej.github.io/dotnet/dacfx/sqlserver/ssms/visualstudio/2026/04/20/sqlprojects-schemacompare.html" rel="alternate" type="text/html" title="Visual Schema Compare for SDK Style SQL Database Projects in Visual Studio and SSMS" /><published>2026-04-20T17:28:49+00:00</published><updated>2026-04-20T17:28:49+00:00</updated><id>https://erikej.github.io/dotnet/dacfx/sqlserver/ssms/visualstudio/2026/04/20/sqlprojects-schemacompare</id><content type="html" xml:base="https://erikej.github.io/dotnet/dacfx/sqlserver/ssms/visualstudio/2026/04/20/sqlprojects-schemacompare.html"><![CDATA[<p>Keeping your SQL database project in sync with a live database is one of the most common — and most tedious — challenges in database development. If you have ever manually compared <code>CREATE TABLE</code> scripts line by line, or tried to figure out which stored procedures drifted out of sync between your source code and development or production environments, <strong>Visual Schema Compare</strong> was built for you.</p>
<h2 id="what-is-visual-schema-compare">What is Visual Schema Compare?</h2>
<p>Visual Schema Compare is a built-in feature of the <a href="https://marketplace.visualstudio.com/items?itemName=ErikEJ.SQLProjectPowerTools">SQL Database Project Power Tools</a> Visual Studio extension and the <a href="https://www.vsixgallery.com/extension/SqlProjectsPowerTools.SSMS.D7DABDC8-FE46-4DA4-BED8-2EAF1A2A578D">SQL Database Project Power Tools for SSMS</a> extension. It surfaces the full power of the <a href="https://learn.microsoft.com/sql/relational-databases/data-tier-applications/data-tier-applications">Microsoft DacFx</a> schema comparison engine — the same engine used by SQL Server Data Tools — directly inside SSMS and Visual Studio, in a purpose-built tool window.</p>
<p>With a single right-click on your database project, you can:</p>
<ul>
<li>Compare your <strong>project</strong> against a <strong>live database</strong> to see what has drifted</li>
<li>Compare a <strong>live database</strong> against your <strong>project</strong> to see what your project is missing</li>
<li>Review <strong>per-object T-SQL diffs</strong> side by side</li>
<li>Copy the <strong>generated deployment script</strong> ready for review or execution</li>
</ul>
<p>No extra tooling, no manual diffing, and no leaving Visual Studio / SSMS.</p>
<h2 id="why-you-need-this">Why You Need This</h2>
<h3 id="the-problem-schema-drift">The Problem: Schema Drift</h3>
<p>Even with a database project in source control, schemas drift. A hotfix goes directly to production, a developer makes a change in their local environment but forgets to commit the SQL script, or an ORM migration runs against a shared database. Over time, the gap between what is in the project and what is in the database grows — and at some point you need to reconcile them.</p>
<p>Traditional approaches involve:</p>
<ul>
<li>Exporting scripts and doing a file diff</li>
<li>Writing your own comparison queries against <code>sys.objects</code></li>
</ul>
<p>None of these fit naturally into a code-first database development workflow.</p>
<h3 id="the-solution-visual-schema-compare">The Solution: Visual Schema Compare</h3>
<p>Visual Schema Compare gives you a first-class schema diff experience without leaving your development environment.</p>
<h2 id="key-capabilities">Key Capabilities</h2>
<ul>
<li><strong>Project-to-database and database-to-project comparison</strong> – Choose which side is the source and which is the target, covering both deployment and reverse-engineering scenarios.</li>
<li><strong>Side-by-side T-SQL diffs</strong> – Selecting any row in the differences grid renders the source and target T-SQL definitions side by side, powered by <a href="https://github.com/mmanela/diffplex">DiffPlex</a>, so you can immediately see what changed.</li>
<li><strong>Actionable differences grid</strong> – The grid shows the object name, object type, difference type (Added, Deleted, Changed), and the update action DacFx recommends.</li>
<li><strong>Deployment script generation</strong> – DacFx generates a full T-SQL deployment script for the detected differences. You can copy it to the clipboard and use it for manual review, peer review, or execution in your own pipeline.</li>
<li><strong>Async comparison</strong> – The comparison runs asynchronously so Visual Studio stays responsive while DacFx processes large schemas.</li>
</ul>
<h2 id="getting-started">Getting Started</h2>
<h3 id="prerequisites">Prerequisites</h3>
<ul>
<li>Visual Studio 2022 (any edition) or SSMS 22</li>
<li><a href="https://marketplace.visualstudio.com/items?itemName=ErikEJ.SQLProjectPowerTools">SQL Database Project Power Tools for Visual Studio</a> installed</li>
<li>or <a href="https://www.vsixgallery.com/extension/SqlProjectsPowerTools.SSMS.D7DABDC8-FE46-4DA4-BED8-2EAF1A2A578D">SQL Database Project Power Tools for SSMS</a> installed</li>
<li>An SDK-style SQL Database Project in your solution</li>
</ul>
<h3 id="running-a-comparison">Running a Comparison</h3>
<ol>
<li>
<p>In <strong>Solution Explorer</strong>, right-click your SQL Database Project.</p>
</li>
<li>
<p>Select <strong>SQL Project Power Tools &gt; Visual Schema Compare (preview)...</strong></p>
</li>
<li>
<p>In the dialog that appears, enter the connection details for your database and choose the <strong>comparison direction</strong>:</p>
<ul>
<li><strong>Database is source</strong> – compares the live database against your project (useful for reverse-engineering changes made directly to the database)</li>
<li><strong>Project is source</strong> – compares your project against the live database (useful before deployment)</li>
</ul>
</li>
<li>
<p>Click <strong>Compare</strong>. The <strong>Visual Schema Compare</strong> tool window opens and populates with the results.</p>
<p><img src="https://raw.githubusercontent.com/ErikEJ/SQLProjectPowerTools/main/img/SchemaCompare.png" alt="Schema Compare tool window" /></p>
</li>
<li>
<p><strong>Browse the differences.</strong> Click any row in the grid to see the side-by-side T-SQL diff for that object.</p>
</li>
<li>
<p>When you are ready to act on the differences, click <strong>Copy Deployment Script</strong> to copy the DacFx-generated T-SQL deployment script to your clipboard.</p>
</li>
</ol>
<h2 id="benefits-of-sql-database-project-power-tools">Benefits of SQL Database Project Power Tools</h2>
<p>Visual Schema Compare is just one of the features in SQL Database Project Power Tools. The extension as a whole is designed to reduce friction in every stage of the database development lifecycle:</p>
<table>
<thead>
<tr>
<th>Feature</th>
<th>Benefit</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Import Database</strong></td>
<td>Bootstrap a new database project from an existing schema in seconds</td>
</tr>
<tr>
<td><strong>Visual Schema Compare</strong></td>
<td>Keep project and database in sync with a visual diff tool</td>
</tr>
<tr>
<td><strong>Static Code Analysis</strong></td>
<td>Catch design, naming, and performance issues before deployment</td>
</tr>
<tr>
<td><strong>Rule Manager</strong></td>
<td>Manage static code analysis rules and get documentation links via an intuitive visual interface</td>
</tr>
<tr>
<td><strong>E/R Diagrams</strong></td>
<td>Auto-generate Mermaid entity/relationship diagrams from your project</td>
</tr>
<tr>
<td><strong>Script Table Data</strong></td>
<td>Generate <code>MERGE</code> statements for seed data directly from live tables</td>
</tr>
<tr>
<td><strong>Scaffold Data API Builder</strong></td>
<td>Generate a Data API Builder configuration file from your project</td>
</tr>
<tr>
<td><strong>.dacpac Explorer</strong></td>
<td>Browse the contents of a <code>.dacpac</code> file in Solution Explorer</td>
</tr>
<tr>
<td><strong>Project Templates</strong></td>
<td>Quickly create new SQL database projects from ready-made templates (Visual Studio only)</td>
</tr>
</tbody>
</table>
<p>Together, these features make SQL database projects a viable choice for teams that want to apply software engineering best practices — source control, code review, CI/CD — to their database schemas while enabling peformant, cross platform build and deployment processes.</p>
<h2 id="acknowledgements">Acknowledgements</h2>
<p>The Visual Schema Compare feature was inspired by the excellent <a href="https://github.com/Axial-SQL/AxialSqlTools/wiki/Database-Schema-Compare">Database Schema Compare</a> feature in <a href="https://github.com/Axial-SQL/AxialSqlTools">Axial SQL Tools</a>. The concept of surfacing DacFx schema comparison inside a Visual Studio tool window, with a per-object T-SQL diff view and a deployment script tab, originated there. Many thanks to the Axial SQL Tools team for sharing the idea openly.</p>
<h2 id="installation">Installation</h2>
<p>Install from the <a href="https://marketplace.visualstudio.com/items?itemName=ErikEJ.SQLProjectPowerTools">Visual Studio Marketplace</a> or search for <strong>SQL Database Project Power Tools</strong> in <strong>Extensions &gt; Manage Extensions</strong> inside Visual Studio 2022.</p>
<p>Feedback, bug reports, and contributions are welcome on the <a href="https://github.com/ErikEJ/SqlProjectPowerTools">GitHub repository</a>.</p>
<hr />
<p><em>If you find the extension useful, please give it a ★★★★★ rating on the <a href="https://marketplace.visualstudio.com/items?itemName=ErikEJ.SQLProjectPowerTools">Visual Studio Marketplace</a> and consider <a href="https://github.com/sponsors/ErikEJ">sponsoring the author on GitHub</a>.</em></p>]]></content><author><name>ErikEJ</name></author><category term="dotnet" /><category term="dacfx" /><category term="sqlserver" /><category term="ssms" /><category term="visualstudio" /><summary type="html"><![CDATA[Keeping your SQL database project in sync with a live database is one of the most common — and most tedious — challenges in database development. If you have ever manually compared CREATE TABLE scripts line by line, or tried to figure out which stored procedures drifted out of sync between your source code and development or production environments, Visual Schema Compare was built for you.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://raw.githubusercontent.com/ErikEJ/SQLProjectPowerTools/main/img/SchemaCompare.png" /><media:content medium="image" url="https://raw.githubusercontent.com/ErikEJ/SQLProjectPowerTools/main/img/SchemaCompare.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry></feed>