如何配置SQL Server Agent发送物业到期前30/15/7天提醒邮件?
没问题,我来一步步帮你搞定这个SQL Server物业到期提醒的需求,从查询优化到邮件配置再到Agent作业,全流程给你捋清楚:
一、先优化你的筛选查询语句
你原来的查询会把已经过期的物业也包含进去,咱们调整一下,精确筛选出刚好提前30/15/7天的记录(避免重复发送提醒):
-- 提前30天的筛选 SELECT * FROM [dbo].[Property] WHERE ExpirationDate BETWEEN GETDATE() AND DATEADD(DAY, 30, GETDATE()) AND DATEDIFF(DAY, GETDATE(), ExpirationDate) = 30; -- 提前15天的筛选 SELECT * FROM [dbo].[Property] WHERE ExpirationDate BETWEEN GETDATE() AND DATEADD(DAY, 15, GETDATE()) AND DATEDIFF(DAY, GETDATE(), ExpirationDate) = 15; -- 提前7天的筛选 SELECT * FROM [dbo].[Property] WHERE ExpirationDate BETWEEN GETDATE() AND DATEADD(DAY, 7, GETDATE()) AND DATEDIFF(DAY, GETDATE(), ExpirationDate) = 7;
如果希望每天都发送直到到期(比如提前30天开始,每天发一次),可以去掉DATEDIFF的条件,但建议加一个AlertSent字段或者单独的提醒记录表,用来跟踪已经发送过的提醒,避免重复骚扰。
二、配置SQL Server数据库邮件(前提步骤)
如果还没配置过数据库邮件,先做这一步:
- 打开SSMS,展开管理 -> 右键数据库邮件,启动配置向导。
- 按照向导创建一个邮件账户(填写你的SMTP服务器信息,比如企业邮箱的SMTP地址、端口、账号密码)。
- 创建一个数据库邮件配置文件,把刚才的邮件账户添加进去,记得设为默认。
三、创建发送提醒邮件的存储过程
咱们写一个存储过程,遍历符合条件的每条记录,单独发送邮件:
CREATE PROCEDURE dbo.SendPropertyExpirationAlerts AS BEGIN SET NOCOUNT ON; -- 定义变量存储物业信息(根据你的表字段调整) DECLARE @PropID INT, @PropName NVARCHAR(100), @ExpDate DATETIME, @ContactEmail NVARCHAR(100); DECLARE @MailProfile NVARCHAR(100) = '你的数据库邮件配置文件名'; -- 替换成你的配置文件名 -- ===== 处理提前30天的提醒 ===== DECLARE @30DayCursor CURSOR; SET @30DayCursor = CURSOR FOR SELECT PropertyID, PropertyName, ExpirationDate, ContactEmail -- 替换成你实际的字段 FROM [dbo].[Property] WHERE ExpirationDate BETWEEN GETDATE() AND DATEADD(DAY, 30, GETDATE()) AND DATEDIFF(DAY, GETDATE(), ExpirationDate) = 30; OPEN @30DayCursor; FETCH NEXT FROM @30DayCursor INTO @PropID, @PropName, @ExpDate, @ContactEmail; WHILE @@FETCH_STATUS = 0 BEGIN -- 发送单条邮件 EXEC msdb.dbo.sp_send_dbmail @profile_name = @MailProfile, @recipients = @ContactEmail, @subject = '⚠️ 物业到期提醒:提前30天', @body = '您好!您负责的物业【' + @PropName + '】将于' + CONVERT(NVARCHAR(50), @ExpDate, 120) + '到期,请及时办理续期或相关手续。'; FETCH NEXT FROM @30DayCursor INTO @PropID, @PropName, @ExpDate, @ContactEmail; END CLOSE @30DayCursor; DEALLOCATE @30DayCursor; -- ===== 处理提前15天的提醒 ===== DECLARE @15DayCursor CURSOR; SET @15DayCursor = CURSOR FOR SELECT PropertyID, PropertyName, ExpirationDate, ContactEmail FROM [dbo].[Property] WHERE ExpirationDate BETWEEN GETDATE() AND DATEADD(DAY, 15, GETDATE()) AND DATEDIFF(DAY, GETDATE(), ExpirationDate) = 15; OPEN @15DayCursor; FETCH NEXT FROM @15DayCursor INTO @PropID, @PropName, @ExpDate, @ContactEmail; WHILE @@FETCH_STATUS = 0 BEGIN EXEC msdb.dbo.sp_send_dbmail @profile_name = @MailProfile, @recipients = @ContactEmail, @subject = '⚠️ 物业到期提醒:提前15天', @body = '您好!您负责的物业【' + @PropName + '】将于' + CONVERT(NVARCHAR(50), @ExpDate, 120) + '到期,请尽快办理续期或相关手续。'; FETCH NEXT FROM @15DayCursor INTO @PropID, @PropName, @ExpDate, @ContactEmail; END CLOSE @15DayCursor; DEALLOCATE @15DayCursor; -- ===== 处理提前7天的提醒 ===== DECLARE @7DayCursor CURSOR; SET @7DayCursor = CURSOR FOR SELECT PropertyID, PropertyName, ExpirationDate, ContactEmail FROM [dbo].[Property] WHERE ExpirationDate BETWEEN GETDATE() AND DATEADD(DAY, 7, GETDATE()) AND DATEDIFF(DAY, GETDATE(), ExpirationDate) = 7; OPEN @7DayCursor; FETCH NEXT FROM @7DayCursor INTO @PropID, @PropName, @ExpDate, @ContactEmail; WHILE @@FETCH_STATUS = 0 BEGIN EXEC msdb.dbo.sp_send_dbmail @profile_name = @MailProfile, @recipients = @ContactEmail, @subject = '⚠️ 物业到期提醒:提前7天', @body = '您好!您负责的物业【' + @PropName + '】将于' + CONVERT(NVARCHAR(50), @ExpDate, 120) + '到期,请立即办理续期或相关手续。'; FETCH NEXT FROM @7DayCursor INTO @PropID, @PropName, @ExpDate, @ContactEmail; END CLOSE @7DayCursor; DEALLOCATE @7DayCursor; END
注意:把代码里的
你的数据库邮件配置文件名替换成你刚才创建的配置文件名称,同时根据你的Property表实际字段调整变量和查询语句。
四、创建SQL Server Agent定时作业
最后一步,设置定时自动执行这个存储过程:
- 打开SSMS,展开SQL Server Agent -> 右键作业 -> 选择新建作业。
- 常规选项卡:给作业起个名字,比如“物业到期自动提醒邮件”。
- 步骤选项卡:点击新建,步骤名称填“执行提醒存储过程”,类型选“Transact-SQL脚本(TSQL)”,数据库选你的业务数据库,命令框里输入:
EXEC dbo.SendPropertyExpirationAlerts;。 - 调度选项卡:点击新建,设置执行频率为“每天”,执行时间选合适的时段(比如早上9点),这样每天都会检查并发送当天需要提醒的邮件。
- (可选)警报选项卡:可以设置作业失败时发送邮件给管理员,方便排查问题。
- 点击确定保存作业,之后可以手动右键作业选择开始作业测试一下,看是否正常发送邮件。
额外注意事项
- 确保SQL Server Agent服务处于启动状态(可以在服务管理器里查看),不然定时作业不会执行。
- 执行存储过程的账户需要有
msdb.dbo.sp_send_dbmail的执行权限,以及访问[dbo].[Property]表的权限。 - 如果你的
Property表没有存储联系人邮箱,可以把@recipients设为固定邮箱(比如管理员邮箱),然后在邮件body里列出所有到期的物业信息。
内容的提问来源于stack exchange,提问作者Tom123
相关产品推荐
相关产品推荐

