{"id":649,"date":"2026-06-24T03:21:46","date_gmt":"2026-06-24T03:21:46","guid":{"rendered":"https:\/\/text.email\/blog\/?p=649"},"modified":"2026-06-24T06:32:32","modified_gmt":"2026-06-24T06:32:32","slug":"sms-alerts-from-microsoft-sql-server","status":"publish","type":"post","link":"https:\/\/text.email\/blog\/sms-alerts-from-microsoft-sql-server\/","title":{"rendered":"How to Send SMS Alerts from Microsoft SQL Server"},"content":{"rendered":"\n<p>Microsoft SQL Server can send email directly from T-SQL using Database Mail and the <code>sp_send_dbmail<\/code> stored procedure.<\/p>\n\n\n\n<p>And with <strong><a href=\"https:\/\/text.email\">text.email<\/a><\/strong>, those emails can become SMS alerts.<\/p>\n\n\n\n<p>The basic method is simple. SQL Server checks a condition. If it&#8217;s bad, SQL Server sends an email using <code>sp_send_dbmail<\/code> to your special text.email address (<code>your-number@your-subdomain.text.email<\/code>).<\/p>\n\n\n\n<p>And <strong>text.email converts that email into an SMS that comes to your phone immediately<\/strong>, ensuring you don&#8217;t miss the alert and you can do something about it ASAP.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Microsoft SQL Server SMS Alerts: Table of Contents<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"#setting-up\">Setting Up Text Alerts in Microsoft SQL Server<\/a><\/li>\n\n\n\n<li><a href=\"#smart-moves\">Other Smart Moves for SQL Server SMS Alerts<\/a><\/li>\n\n\n\n<li><a href=\"#get-started\">Ready to Get Started with Microsoft SQL Server SMS Alerts?<\/a><\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"setting-up\">Setting Up Text Alerts in Microsoft SQL Server<\/h2>\n\n\n\n<p>Here&#8217;s how to get this set up&#8230;<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Prerequisites<\/h3>\n\n\n\n<p>You&#8217;ll need the following things before we dive in:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>A Microsoft SQL Server instance with Database Mail configured (here are Microsoft&#8217;s <a href=\"https:\/\/learn.microsoft.com\/en-us\/sql\/relational-databases\/database-mail\/configure-database-mail?view=sql-server-ver17\">instructions<\/a>)<\/li>\n\n\n\n<li>A Database Mail profile, such as <code>TextEmailAlerts<\/code><\/li>\n\n\n\n<li>A <a href=\"https:\/\/text.email\">text.email<\/a> address<\/li>\n\n\n\n<li>Optional but recommended: SQL Server Agent, so the checks can run automatically on a schedule<\/li>\n<\/ul>\n\n\n\n<p>To get your email-to-SMS address, go to text.email. Sign up for an account with your email address, pick a plan, and choose a private subdomain.<\/p>\n\n\n\n<p>Now you&#8217;ll be able to send a text alert to yourself at an address like <code>15551234567@your-subdomain.text.email<\/code>.<\/p>\n\n\n\n<p>If you need these alerts to go to multiple people, you can set up a quick <a href=\"https:\/\/text.email\/blog\/distribution-lists\/\">distribution list<\/a> in text.email, with an address like <code>dba-alerts@your-subdomain.text.email<\/code>. I&#8217;ll cover those a bit more later on.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 1: Send a Test SMS from SQL Server<\/h3>\n\n\n\n<p>Once Database Mail is configured, start with a simple test:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>EXEC msdb.dbo.sp_send_dbmail\n    @profile_name = 'TextEmailAlerts',\n    @recipients = 'your-number@your-subdomain.text.email',\n    @subject = 'SQL Server test alert',\n    @body = 'This is a test SMS alert from SQL Server using text.email.';<\/code><\/pre>\n\n\n\n<p>(Obviously, replace <code>TextEmailAlerts<\/code> with your Database Mail profile name and <code>your-number@your-subdomain.text.email<\/code> with your actual text.email address.)<\/p>\n\n\n\n<p>If everything is configured correctly, <strong>SQL Server will send an email and text.email will deliver it as an SMS message<\/strong>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 2: Choose the condition for your SMS alerts<\/h3>\n\n\n\n<p>You want to use these text alerts for the most critical situations (so you don&#8217;t grow blind to them).<\/p>\n\n\n\n<p>Here are four examples of how you can use them right.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Alert if the most recent record is too old<\/h4>\n\n\n\n<p>A key database health check is <strong>making sure a table is still receiving new records<\/strong>.<\/p>\n\n\n\n<p>Like&#8230; if you have an <code>Orders<\/code> table and you expect new orders to arrive at least every 30 minutes. If the newest order is older than 30 minutes, that could mean your website, API, import process, or payment flow is broken.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>DECLARE @LastOrderUtc datetime2;\nDECLARE @Message nvarchar(max);\n\nSELECT @LastOrderUtc = MAX(CreatedUtc)\nFROM dbo.Orders;\n\nIF @LastOrderUtc IS NULL\n   OR @LastOrderUtc &lt; DATEADD(MINUTE, -30, SYSUTCDATETIME())\nBEGIN\n    SET @Message = CONCAT(\n        'SQL Server alert: No recent orders. Last order UTC: ',\n        COALESCE(CONVERT(varchar(30), @LastOrderUtc, 120), 'none')\n    );\n\n    EXEC msdb.dbo.sp_send_dbmail\n        @profile_name = 'TextEmailAlerts',\n        @recipients = 'dba-alerts@your-subdomain.text.email',\n        @subject = 'SQL Alert: Orders stale',\n        @body = @Message;\nEND;<\/code><\/pre>\n\n\n\n<p>This sends an SMS only if the newest order is missing or too old.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Alert if a table has too many rows<\/h4>\n\n\n\n<p>Another useful check is monitoring a queue table. If too many rows build up, <strong>it may mean a background process is stuck<\/strong>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>DECLARE @QueueCount int;\nDECLARE @Message nvarchar(max);\n\nSELECT @QueueCount = COUNT(*)\nFROM dbo.MessageQueue\nWHERE ProcessedUtc IS NULL;\n\nIF @QueueCount &gt; 1000\nBEGIN\n    SET @Message = CONCAT(\n        'SQL Server alert: MessageQueue backlog is ',\n        @QueueCount,\n        ' unprocessed rows.'\n    );\n\n    EXEC msdb.dbo.sp_send_dbmail\n        @profile_name = 'TextEmailAlerts',\n        @recipients = 'dba-alerts@your-subdomain.text.email',\n        @subject = 'SQL Alert: Queue backlog',\n        @body = @Message;\nEND;<\/code><\/pre>\n\n\n\n<p>This is helpful for email queues, SMS queues, billing queues, import queues, webhook queues, or any other table where records should be processed quickly.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Alert if a table has too few rows<\/h4>\n\n\n\n<p>For example, maybe a reporting table should receive at least 500 records per day. If it does not, <strong>something upstream may have failed<\/strong>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>DECLARE @TodayCount int;\nDECLARE @Message nvarchar(max);\n\nSELECT @TodayCount = COUNT(*)\nFROM dbo.ImportedEvents\nWHERE CreatedUtc &gt;= CONVERT(date, SYSUTCDATETIME());\n\nIF @TodayCount &lt; 500\nBEGIN\n    SET @Message = CONCAT(\n        'SQL Server alert: ImportedEvents has only ',\n        @TodayCount,\n        ' rows today. Expected at least 500.'\n    );\n\n    EXEC msdb.dbo.sp_send_dbmail\n        @profile_name = 'TextEmailAlerts',\n        @recipients = 'dba-alerts@your-subdomain.text.email',\n        @subject = 'SQL Alert: Low import volume',\n        @body = @Message;\nEND;<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Alert if new errors appear<\/h4>\n\n\n\n<p>If your application writes errors to a database table, <strong>SQL Server can text you when new critical errors appear<\/strong>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>DECLARE @ErrorCount int;\nDECLARE @Message nvarchar(max);\n\nSELECT @ErrorCount = COUNT(*)\nFROM dbo.ApplicationErrors\nWHERE Severity = 'Critical'\n  AND CreatedUtc &gt;= DATEADD(MINUTE, -5, SYSUTCDATETIME());\n\nIF @ErrorCount &gt; 0\nBEGIN\n    SET @Message = CONCAT(\n        'SQL Server alert: ',\n        @ErrorCount,\n        ' critical application errors in the last 5 minutes.'\n    );\n\n    EXEC msdb.dbo.sp_send_dbmail\n        @profile_name = 'TextEmailAlerts',\n        @recipients = 'dba-alerts@your-subdomain.text.email',\n        @subject = 'SQL Alert: Critical errors',\n        @body = @Message;\nEND;<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Step 3: Run these checks automatically<\/h3>\n\n\n\n<p>Now that you have your check(s) in place, you&#8217;ll need them to run automatically. The easiest way is with SQL Server Agent.<\/p>\n\n\n\n<p>In SQL Server Management Studio:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Open SQL Server Agent.<\/li>\n\n\n\n<li>Create a new Job.<\/li>\n\n\n\n<li>Add a T-SQL job step.<\/li>\n\n\n\n<li>Paste in one of the alert scripts above.<\/li>\n\n\n\n<li>Create a schedule, such as every 5 minutes, every 15 minutes, or once per hour.<\/li>\n<\/ol>\n\n\n\n<p>For example, a stale-orders check might run every 5 minutes. A daily volume check might run once per morning. A queue backlog check might run every 1 or 2 minutes if it is monitoring something critical.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 4: Prevent alert spam<\/h3>\n\n\n\n<p>You <em>really<\/em> don&#8217;t want to text yourself every minute for the same ongoing problem.<\/p>\n\n\n\n<p>A quick way to prevent alert spam is to <strong>create a small table that tracks when each alert was last sent<\/strong>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>CREATE TABLE dbo.SqlSmsAlertLog\n(\n    AlertName nvarchar(100) NOT NULL PRIMARY KEY,\n    LastSentUtc datetime2 NOT NULL\n);<\/code><\/pre>\n\n\n\n<p>Then check that table before sending another SMS.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>DECLARE @AlertName nvarchar(100) = 'Orders stale';\nDECLARE @LastOrderUtc datetime2;\nDECLARE @LastSentUtc datetime2;\nDECLARE @Message nvarchar(max);\n\nSELECT @LastOrderUtc = MAX(CreatedUtc)\nFROM dbo.Orders;\n\nSELECT @LastSentUtc = LastSentUtc\nFROM dbo.SqlSmsAlertLog\nWHERE AlertName = @AlertName;\n\nIF (\n       @LastOrderUtc IS NULL\n       OR @LastOrderUtc &lt; DATEADD(MINUTE, -30, SYSUTCDATETIME())\n   )\n   AND (\n       @LastSentUtc IS NULL\n       OR @LastSentUtc &lt; DATEADD(MINUTE, -30, SYSUTCDATETIME())\n   )\nBEGIN\n    SET @Message = CONCAT(\n        'SQL Server alert: No recent orders. Last order UTC: ',\n        COALESCE(CONVERT(varchar(30), @LastOrderUtc, 120), 'none')\n    );\n\n    EXEC msdb.dbo.sp_send_dbmail\n        @profile_name = 'TextEmailAlerts',\n        @recipients = 'dba-alerts@your-subdomain.text.email',\n        @subject = 'SQL Alert: Orders stale',\n        @body = @Message;\n\n    MERGE dbo.SqlSmsAlertLog AS target\n    USING (SELECT @AlertName AS AlertName) AS source\n    ON target.AlertName = source.AlertName\n    WHEN MATCHED THEN\n        UPDATE SET LastSentUtc = SYSUTCDATETIME()\n    WHEN NOT MATCHED THEN\n        INSERT (AlertName, LastSentUtc)\n        VALUES (@AlertName, SYSUTCDATETIME());\nEND;<\/code><\/pre>\n\n\n\n<p>This version sends the SMS only if:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The orders table is stale<\/li>\n\n\n\n<li>The same alert has not already been sent in the last 30 minutes<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"smart-moves\">Other Smart Moves for SQL Server SMS Alerts<\/h2>\n\n\n\n<p>Those are the key setup steps. These are some refinements. <\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Keep the SMS short<\/h3>\n\n\n\n<p>SMS alerts should be brief. Include the system name, the problem, and the most important number or timestamp.<\/p>\n\n\n\n<p>For example, this is good:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>SQL Alert: Orders stale. Last order UTC: 2026-06-23 14:02:11<\/code><\/pre>\n\n\n\n<p>This is too long and will get split into multiple messages:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>The order processing subsystem has not inserted a new row into the Orders table recently and this may indicate a possible problem with the website, API, database, or payment processor...<\/code><\/pre>\n\n\n\n<p>(Though you <em>could<\/em> do this with text.email&#8217;s <a href=\"https:\/\/text.email\/blog\/sms-formatting\/\" data-type=\"post\" data-id=\"213\">SMS formatting<\/a>, it&#8217;s probably better to just set up the alerts right in SQL Server.)<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Use a distribution list for team alerts<\/h3>\n\n\n\n<p>As I mentioned earlier, if you need to send alerts to more than one person, you can use a text.email <a href=\"https:\/\/text.email\/blog\/distribution-lists\/\">distribution list<\/a>.<\/p>\n\n\n\n<p>That makes it easier to add or remove recipients without changing SQL Server code. SQL Server keeps sending to the same address, while you manage the actual phone numbers inside text.email.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Use scheduled routing for on-call teams<\/h3>\n\n\n\n<p>If your team has different people responsible at different times, use <a href=\"https:\/\/text.email\/blog\/scheduled-sms-routing\/\">scheduled SMS routing<\/a> in text.email. <strong>SQL Server can keep sending to the same address, while text.email decides who should receive the SMS based on the schedule.<\/strong><\/p>\n\n\n\n<p>So, for example, only the one poor sucker who&#8217;s on call overnight gets the alerts between 12 AM and 7 AM.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Include the server or database name<\/h3>\n\n\n\n<p>If you manage more than one SQL Server, include the server name or database name in the message.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>DECLARE @Message nvarchar(max);\n\nSET @Message = CONCAT(\n    'SQL alert on ',\n    @@SERVERNAME,\n    ': Orders table is stale.'\n);<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"get-started\">Ready to Get Started with Microsoft SQL Server SMS Alerts?<\/h2>\n\n\n\n<p>So yeah, a database table having a few extra rows doesn&#8217;t sound as critical as, say, the server being on fire. But if you&#8217;ve ever been burned (no pun intended) before, you know that <strong>many problems show up in the database before they show up anywhere else<\/strong>.<\/p>\n\n\n\n<p>Your database knows when:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Customers stopped signing up<\/li>\n\n\n\n<li>Orders stopped arriving<\/li>\n\n\n\n<li>Payments stopped processing<\/li>\n\n\n\n<li>A queue is growing<\/li>\n\n\n\n<li>A background worker stopped updating records<\/li>\n\n\n\n<li>Error logs are filling up<\/li>\n\n\n\n<li>Expected data did not arrive<\/li>\n<\/ul>\n\n\n\n<p>By combining SQL Server Database Mail with text.email, <strong>you can turn those database conditions into SMS alerts without building a separate monitoring application<\/strong>.<\/p>\n\n\n\n<p><strong>Ready to get started<\/strong> with text.email and get your Microsoft SQL Server text alerts going in the next few <em>minutes<\/em>? Sign up for <a href=\"https:\/\/text.email\">text.email<\/a>, pick a plan, follow the instructions in this article, and you and your team will be good to go.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>How to get text alerts for Microsoft SQL Server issues in a matter of minutes by using text.email for email to SMS.<\/p>\n","protected":false},"author":1,"featured_media":655,"comment_status":"closed","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3,4],"tags":[],"class_list":["post-649","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-email-to-sms","category-system-alerts"],"_links":{"self":[{"href":"https:\/\/text.email\/blog\/wp-json\/wp\/v2\/posts\/649","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/text.email\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/text.email\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/text.email\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/text.email\/blog\/wp-json\/wp\/v2\/comments?post=649"}],"version-history":[{"count":5,"href":"https:\/\/text.email\/blog\/wp-json\/wp\/v2\/posts\/649\/revisions"}],"predecessor-version":[{"id":654,"href":"https:\/\/text.email\/blog\/wp-json\/wp\/v2\/posts\/649\/revisions\/654"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/text.email\/blog\/wp-json\/wp\/v2\/media\/655"}],"wp:attachment":[{"href":"https:\/\/text.email\/blog\/wp-json\/wp\/v2\/media?parent=649"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/text.email\/blog\/wp-json\/wp\/v2\/categories?post=649"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/text.email\/blog\/wp-json\/wp\/v2\/tags?post=649"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}