为什么INSERT触发器只发送一封电子邮件?

时间:2014-10-19 12:10:04

标签: sql-server sql-server-2008 tsql email triggers

我有一个包含以下结构的表

id | full_name | email
-------------------------------
1  | Ahmad     | ahmad@some.com
2  | Jack      | jack@another.com
3  | Mike      | mike@yetanother.com
. .    ..          ..

等等。

我创建了以下触发器,向刚刚插入电子邮件的人发送电子邮件(作为欢迎信息):

create TRIGGER welcome_user ON users
AFTER INSERT
AS
begin
  declare @email varchar(100)
  declare @full_name varchar(200)
  declare @html varchar(4000)

  select @email=i.email,@full_name=i.full_name from inserted i


  set @html = 'Dear ' + @full_name + '<br><br> Welcome...'  

begin
  exec msdb.dbo.sp_send_dbmail  @profile_name =  'SQL Database Mail'
     ,  @recipients =   @email
     ,  @copy_recipients = 'admin@mycompany.com' 
     ,  @from_address = 'admin@mycompany.com'
     ,  @subject =  'Welcome'
     ,  @body_format = 'HTML'
     ,  @body = @html

end

end
GO

现在,如果插入一行,上面的代码将起作用:

insert into users (id,full_name,email) values (900,'Jason','jason@email.com')

用户将收到一封电子邮件,我将被复制(因为我可以访问admin@mycompany.com

但是当一串插入所有行时会出现问题,执行以下操作:

insert into users (id,full_name,email) 
   select id,full_name,email from temp_users where validated='Y'

在上面的示例中,只发送了一封电子邮件(插入的第一行)。其他的插入到表中,但没有向他们发送电子邮件。副本都没有发给我。

可能导致这种情况发生的原因是什么?

1 个答案:

答案 0 :(得分:1)

每个语句触发一次 - 每行一次。因此,inserted表在触发器中有多行 - 您只使用一行。你应该做的是将插入的表中的记录复制到表变量中并循环它。

正如@Aaron Bertrand指出的那样 - 更好的解决方案是从触发器中删除邮件依赖关系到存储过程 - 异步处理。使用此解决方案,您的触发器将填充充当队列的表。然后,您将拥有一个读取此队列并发送电子邮件的过程。可以安排此过程(使用SQL代理或Service Broker),甚至可以手动运行。有关详细信息,请参阅herehere