解决方法
首先你需要设置数据库邮件 – 如果你还没有这样做,这个问题可能有帮助:
> Scripting setup of database mail
那么你需要一个触发器:
CREATE TRIGGER dbo.whatever ON dbo.wherever FOR INSERT AS BEGIN SET NOCOUNT ON; IF EXISTS (SELECT 1 FROM inserted WHERE speed > 100) BEGIN EXEC msdb.dbo.sp_send_dbmail @recipients = 'whoever@yourcompany.com',@profile_name = 'default',@subject = 'Someone was speeding',@body = 'Yep,they sure were.'; END END GO
现在,你可能会说你想要插入的数据实际上被包含在电子邮件中.而您的第一个倾向是声明一些局部变量并将其从插入中分配出来 – 这不起作用,因为您的触发器可能会响应多行插入.所以正确的方法是:
CREATE TRIGGER dbo.whatever ON dbo.wherever FOR INSERT AS BEGIN SET NOCOUNT ON; DECLARE @body NVARCHAR(MAX) = N''; SELECT @body += CHAR(13) + CHAR(10) + RTRIM(some_col) FROM inserted; IF EXISTS (SELECT 1 FROM inserted WHERE speed > 100) BEGIN EXEC msdb.dbo.sp_send_dbmail @recipients = 'whoever@yourcompany.com',@subject = 'At least one person was speeding',@body = @body; END END GO
这一切都说,我不是从触发器发送电子邮件的大粉丝.即使数据库邮件使用服务代理,因此是异步的,我更倾向于填充队列表,并有一个后台线程,并发送所有相应的电子邮件.关于这个的twothree好的事情是:
>最小化触发触发器的外部事务的潜在延迟 – 触发器中的逻辑越复杂,您进行该过程的速度就越慢.>由于电子邮件的发送可能不是这个行被插入的微秒,所以你可以很容易地摆动后台进程的时间 – 这样就避免了非常小心地检查表格,整天很少次将永远不得不做任何事情.如@goodeye所指出的那样,保持此过程是分开的,可以防止进程的电子邮件部分的错误干扰原始的DML(在这种情况下,sp_send_dbmail的无效参数(我无意中建议的 – 阻止插入)).