Рекомендуется отсоединить код отправки электронной почты от триггера - в триггере вставьте необходимую информацию в таблицу «Ожидающие электронные письма».Затем создайте задание, которое периодически проверяет таблицу и отправляет электронную почту.
Вам также необходимо переписать триггер, чтобы справиться с многострочными вставками и обновлениями.inserted
- это псевдо-таблица, которая может содержать несколько строк.
Так что я бы написал триггер примерно так:
CREATE TRIGGER CheckForDirty
ON dbo.Messages
FOR INSERT,UPDATE
AS
INSERT INTO PendingEmails (Recipients,Subject,Body)
SELECT 'message@email.com','Test e-mail sent from database mail','Someone said something dirty'
FROM inserted
WHERE CHARINDEX('BadWord',Body) > 0
Хотя я предполагаю, что фактическое телосообщение, которое вы создаете, может опираться на дополнительную информацию, чтобы помочь определить, какое сообщение замешано.
Хорошо, если мы собираемся встроить это в полный пример, нам нужно определить PendingEmails:
CREATE TABLE PendingEmails (
PendingEmailID int IDENTITY(1,1) not null,
Recipients varchar(max) not null,
Subject nvarchar(255) not null,
Body nvarchar(max) not null,
constraint PK_PendingEmails PRIMARY KEY (PendingEmailID)
)
А теперь мы напишем сохраненный процесс, который может обрабатывать ожидающие электронные письма:
CREATE PROCEDURE DispatchPendingEmails
AS
declare @PendingEmailID int
declare @Recipients varchar(max)
declare @Subject nvarchar(255)
declare @Body nvarchar(max)
while exists(select * from PendingEmails)
begin
select top 1 @PendingEmailID = PendingEmailID,@Recipients = Recipients,
@Subject = Subject, @Body = Body from PendingEmails
exec msdb.dbo.sp_send_dbmail @recipients = @Recipients, @subject = @Subject, @body = @Body
delete from PendingEmails where PendingEmailID = @PendingEmailID
end
И, наконец, нам нужно создать задание.Обычно я делаю это через SSMS, но если вы хотите, чтобы это было написано по сценарию (вам нужно будет заменить другое имя базы данных в строке sp_add_jobstep, и это настроено для запуска отправки каждые пять минут.задокументировано в MSDN):
USE [msdb]
GO
DECLARE @jobId BINARY(16)
EXEC msdb.dbo.sp_add_job @job_name=N'DispatchPendingEmails',
@enabled=1,
@notify_level_eventlog=0,
@notify_level_email=2,
@notify_level_netsend=2,
@notify_level_page=2,
@delete_level=0,
@category_name=N'[Uncategorized (Local)]',
@owner_login_name=N'sa', @job_id = @jobId OUTPUT
select @jobId
GO
EXEC msdb.dbo.sp_add_jobserver @job_name=N'DispatchPendingEmails', @server_name = N'SYSTEMS86\SQL2K8'
GO
USE [msdb]
GO
EXEC msdb.dbo.sp_add_jobstep @job_name=N'DispatchPendingEmails', @step_name=N'ExecSP',
@step_id=1,
@cmdexec_success_code=0,
@on_success_action=1,
@on_fail_action=2,
@retry_attempts=0,
@retry_interval=0,
@os_run_priority=0, @subsystem=N'TSQL',
@command=N'exec DispatchPendingEmails',
@database_name=N'Database', --<-- This needs editing
@flags=0
GO
USE [msdb]
GO
EXEC msdb.dbo.sp_update_job @job_name=N'DispatchPendingEmails',
@enabled=1,
@start_step_id=1,
@notify_level_eventlog=0,
@notify_level_email=2,
@notify_level_netsend=2,
@notify_level_page=2,
@delete_level=0,
@description=N'',
@category_name=N'[Uncategorized (Local)]',
@owner_login_name=N'sa',
@notify_email_operator_name=N'',
@notify_netsend_operator_name=N'',
@notify_page_operator_name=N''
GO
USE [msdb]
GO
DECLARE @schedule_id int
EXEC msdb.dbo.sp_add_jobschedule @job_name=N'DispatchPendingEmails', @name=N'QuiteOften',
@enabled=1,
@freq_type=4,
@freq_interval=1,
@freq_subday_type=4,
@freq_subday_interval=5,
@freq_relative_interval=0,
@freq_recurrence_factor=1,
@active_start_date=20110218,
@active_end_date=99991231,
@active_start_time=0,
@active_end_time=235959, @schedule_id = @schedule_id OUTPUT
select @schedule_id
GO