【问题标题】:Sending mail on a TRIGGER stops insert from taking place (and email doesnt send)在 TRIGGER 上发送邮件会阻止插入发生(并且电子邮件不会发送)
【发布时间】:2012-06-11 19:25:16
【问题描述】:

我在 INSERT 上有一个简单的触发器

ALTER TRIGGER [dbo].[SendErrorEmail]
   ON  [dbo].[tblNewErrorLog]
   FOR INSERT
AS 
BEGIN   


    EXEC msdb.dbo.sp_send_dbmail 
        @profile_name='myprofile',
        @recipients='me@me.com',
        @subject='error in the database',
        @body = 'check it out'

END
  • 如果我使用 Management Studio 手动添加行,一切正常,添加行的电子邮件已发送。
  • 如果通过服务记录错误,则什么也没有。没有电子邮件,没有新行。
  • 如果我删除触发器 - 事情会按预期工作,则添加行。
  • 如果我保留触发器,但删除电子邮件 SP,则可以。添加了新行。

那么,错误显然与电子邮件有关,也许是安全性?我已尝试登录服务用于连接数据库的凭据,如果我手动添加一行,它就可以工作。

我也有点担心,即使邮件发不出去,插入也会失败,这是为什么呢?

欢迎提出从何处着手解决此问题的想法。

谢谢!

编辑: 从代码中删除了 try catch 一般整理

【问题讨论】:

  • 您不应将发送电子邮件的失败与触发器结合起来。相反,要么在相关表中添加一个标志列,然后运行一个单独的进程,为未标志的行发送电子邮件,或者使用一个队列表。发送电子邮件时会出现很多问题,您不想希望将记录错误的成功率与这些问题联系起来。
  • 无论发生什么错误都会被 BEGIN CATCH、END CATCH 吃掉,删除它或在异常处理中添加额外的错误日志
  • 抱歉,try catch 是我粘贴我的故障排除尝试的副本,如果我完全删除 try catch 也会发生同样的事情。我想看看如果捕获被击中,该行是否仍会被插入
  • @LasseV.Karlsen:sp_send_dbmail 已经将触发器与任何 SMTP 活动分离。它使用内部 SQL Server 队列 (Service Broker),而 SMTP 活动由外部进程处理。

标签: sql-server email triggers


【解决方案1】:

触发器在对msdb.dbo.sp_send_dbmail 过程没有执行权限的上下文中执行。您很可能陷入了受限的EXECUTE AS 沙盒,请参阅Understanding Execution Context。这将与您描述的问题完全一样:它适用于 SSMS,但不适用于您的应用程序。

有关如何使用代码签名为在 EXECUTE AS 上下文沙箱中运行的代码授予执行权限的示例,请参阅 Call a procedure in another database from an activated procedure

如果代码没有在 EXECUTE As 下运行,那么只是简单的权限问题。您可以将 sp_send_dbmail 的 [msdb] 访问权限和 EXECUTE 权限授予您应用程序使用的服务帐户,或者您可以再次使用上述代码签名。

【讨论】:

  • 感谢您的快速回复。我为有问题的用户在 sp_send_dbmail 上添加了 exec 权限,这很好。我不喜欢插入失败的事实。我猜它的设计是,如果链接到动作的触发器失败,一切都会失败?
  • 触发器默认使用SET XACT_ABORT ON执行。
猜你喜欢
  • 1970-01-01
  • 2013-07-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多