<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Manuel Enzo</title>
    <description>The latest articles on DEV Community by Manuel Enzo (@manuelenzo).</description>
    <link>https://dev.to/manuelenzo</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2717400%2Ffbf0bba8-7a82-41a5-9c19-bf66a1eb560b.jpeg</url>
      <title>DEV Community: Manuel Enzo</title>
      <link>https://dev.to/manuelenzo</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/manuelenzo"/>
    <language>en</language>
    <item>
      <title>Why I Built a Free SSMS Extension to Stop Destructive Queries</title>
      <dc:creator>Manuel Enzo</dc:creator>
      <pubDate>Sun, 26 Jul 2026 12:54:35 +0000</pubDate>
      <link>https://dev.to/manuelenzo/why-i-built-a-free-ssms-extension-to-stop-destructive-queries-npo</link>
      <guid>https://dev.to/manuelenzo/why-i-built-a-free-ssms-extension-to-stop-destructive-queries-npo</guid>
      <description>&lt;p&gt;The moment that started it&lt;/p&gt;

&lt;p&gt;A colleague of mine was cleaning up some old records in a staging environment. Same query he'd run a dozen times before, except this time he was connected to production. He hit F5. No WHERE clause.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;47,000 rows gone in milliseconds&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;We recovered from a backup, lost about two hours, and nobody got fired. But it stuck with me:** SSMS will let you delete an entire production table with the same amount of friction as running a SELECT 1**. No pause, no confirmation, nothing. The tool that DBAs and backend developers spend all day in has zero built-in protection against the single most common way people destroy data.&lt;/p&gt;

&lt;p&gt;So I built one.&lt;/p&gt;

&lt;h2&gt;
  
  
  What SQL Guard does
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;SQL Guard&lt;/strong&gt; is a free SSMS extension (18 through 22) that inspects your query the moment you press F5, and pauses execution if it matches a known destructive pattern:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;DELETE without WHERE&lt;/li&gt;
&lt;li&gt;UPDATE without WHERE&lt;/li&gt;
&lt;li&gt;TRUNCATE TABLE&lt;/li&gt;
&lt;li&gt;DROP TABLE / DROP DATABASE / DROP PROCEDURE&lt;/li&gt;
&lt;li&gt;ALTER DATABASE&lt;/li&gt;
&lt;li&gt;Dangerous EXEC calls&lt;/li&gt;
&lt;li&gt;MERGE without a filter&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When one of these fires, you get a dialog showing exactly what object would be affected, with three options: cancel, run anyway, or run and ignore for the rest of the session. The point isn't to block you — it's to make the action conscious. Most accidental damage happens because muscle memory took over, not because someone genuinely meant to wipe a table.&lt;/p&gt;

&lt;h2&gt;
  
  
  How the detection works
&lt;/h2&gt;

&lt;p&gt;Nothing exotic here, and honestly that's by design. SQL Guard runs a lightweight pattern-matching pass over the query text before it hits the connection. No parsing tree, no round-trip to the server, no measurable latency — it runs in under a millisecond, so you never notice it on normal queries.&lt;/p&gt;

&lt;p&gt;The core idea is simple: certain statements are only safe when scoped by a WHERE clause, and the extension checks for that clause's absence rather than trying to understand the full semantics of the query. That keeps false positives low and means it works the same way whether you're on SQL Server 2016 or the latest version.&lt;/p&gt;

&lt;p&gt;A conscious design choice: whitelisting is per-table, per-rule — never a blanket bypass. If you have a staging table that legitimately gets truncated on every import, you whitelist that specific table for that specific rule. You don't get an "ignore everything" switch, because that switch is exactly what erases the safety net the first time you forget you flipped it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why it stays local
&lt;/h2&gt;

&lt;p&gt;SQL Guard never sends your query text, connection strings, or database names anywhere. Everything happens inside the SSMS process. The only optional telemetry is anonymous crash reporting (via Sentry) for stack traces — never query content. For anyone working with production data, that's not a nice-to-have, it's the only acceptable design.&lt;/p&gt;

&lt;p&gt;Installing it&lt;br&gt;
Windows, SSMS 18–22&lt;br&gt;
Zero configuration — the installer registers with every SSMS version it finds&lt;br&gt;
Free, no license key, no trial period&lt;/p&gt;

&lt;p&gt;If you want to try it: &lt;a href="https://sqlguard.app/" rel="noopener noreferrer"&gt;https://sqlguard.app/&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'd love feedback on
&lt;/h2&gt;

&lt;p&gt;The rule set covers the "classics" — the patterns that show up over and over in production-incident postmortems. If you've got a destructive pattern that's bitten you and isn't in that list, I want to hear about it. I read every piece of feedback myself.&lt;/p&gt;

&lt;p&gt;Backups and a recovery plan are still non-negotiable — SQL Guard reduces the chance of a destructive query, it doesn't replace either. But reducing the chance is worth a lot when the alternative is a Saturday spent restoring from a transaction log.&lt;/p&gt;

</description>
      <category>database</category>
      <category>security</category>
      <category>sql</category>
      <category>tools</category>
    </item>
  </channel>
</rss>
