我正在尝试开发邮件触发器。有人可以协助如何实现这一点,以便在用户插入记录时检查“速度”字段,以便当插入值超过 100 时,将邮件发送到指定地址。
问问题
87253 次
1 回答
52
首先,您需要设置数据库邮件 - 如果您还没有这样做,这个问题可能会有所帮助:
然后你需要一个触发器:
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
现在,您可能会说您希望插入的数据实际包含在电子邮件中。您的第一个倾向是声明一些局部变量并从中分配它们inserted
- 这不起作用,因为您的触发器可能响应多行插入。所以正确的做法是:
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',
@profile_name = 'default',
@subject = 'At least one person was speeding',
@body = @body;
END
END
GO
总而言之,我不是从触发器发送电子邮件的忠实粉丝。尽管数据库邮件使用服务代理,因此是异步的,但我更倾向于填充队列表,并有一个后台线程来发送所有适当的电子邮件。关于此的两个三个好处是:
- 您可以最大限度地减少提交触发触发器的外部事务的潜在延迟 - 触发器中的逻辑越复杂,您执行该过程的速度就越慢。
- 由于在插入行的微秒内发送电子邮件可能不是必需的,因此您可以轻松地波动后台进程的时间 - 这避免了必须一整天都检查表的时间,而这种情况很少会发生永远不得不实际做任何事情。
- 正如@goodeye 指出的那样,将这个过程分开可以防止该过程的电子邮件部分中的错误干扰原始 DML(在他们的情况下,一个无效的参数
sp_send_dbmail
- 我无意中建议 - 阻止了插入)。
于 2012-05-25T13:45:28.393 回答