Сбои почты в базе данных SQL Server 2005
Я запускаю базу данных почты на коробке SQL 2005. Иногда письма не отправляются, запрашивая таблицу msdb.dbo.sysmail_mailitems, и я вижу, что есть элементы с sent_status "2", что не удалось. Я могу запросить таблицу sysmail_faileditems, чтобы вывести список всех неудачных писем.
Могу ли я в любом случае обработать / повторно отправить эти письма с ошибками?
Было бы разумно создать ежедневную работу для запроса этой таблицы с циклическим использованием CURSOR для повторной отправки писем по одному, а затем удаления их из таблицы по одному.
Если у вас есть лучшее предложение / идеи, пожалуйста, дайте мне знать.
Большое спасибо Карл
2 ответа
Прежде всего, я предлагаю вам запросить элементы с ошибками, чтобы определить вашу основную причину ошибки:
SELECT items.subject ,
items.last_mod_date ,
l.description
FROM dbo.sysmail_faileditems AS items
INNER JOIN dbo.sysmail_event_log AS l ON items.mailitem_id = l.mailitem_id
Если это не может быть легко исправлено, вы можете отправить их повторно, просматривая таблицу sysmail_mailitems и отправляя их повторно в зависимости от типа ошибки (тайм-ауты и т. Д.) В журнале failitems - несколько хороших примеров в предложениях этого блога: http://justgeeks.blogspot.co.uk/2007/05/resending-sysmail-emails.html
Мой личный фаворит:
CREATE PROCEDURE sysmail_resend_timeout
AS
BEGIN
SET NOCOUNT ON
DECLARE SYSMAIL_LOG_RESEND_CURSOR CURSOR READ_ONLY
FOR
SELECT DISTINCT
l.mailitem_id ,
p.name ,
m.recipients ,
m.subject ,
m.body_format ,
m.body
FROM msdb.dbo.sysmail_log l WITH ( NOLOCK )
JOIN msdb.dbo.sysmail_mailitems m WITH ( NOLOCK ) ON m.mailitem_id = l.mailitem_id
JOIN msdb.dbo.sysmail_profile p WITH ( NOLOCK ) ON p.profile_id = m.profile_id
WHERE l.event_type = 3
AND m.sent_status = 2
AND l.description LIKE '%The operation has timed out%'
ORDER BY l.mailitem_id
OPEN SYSMAIL_LOG_RESEND_CURSOR
WHILE ( 1 = 1 )
BEGIN
DECLARE @mailitem_id INT ,
@profile_name NVARCHAR(128) ,
@recipients VARCHAR(MAX) ,
@subject NVARCHAR(255) ,
@body_format VARCHAR(20) ,
@body NVARCHAR(MAX)
FETCH NEXT FROM SYSMAIL_LOG_RESEND_CURSOR INTO @mailitem_id, @profile_name, @recipients, @subject, @body_format, @body
IF NOT @@FETCH_STATUS = 0
BEGIN
BREAK
END
PRINT CONVERT(VARCHAR, GETDATE(), 121) + CHAR(9) + CONVERT(VARCHAR, @mailitem_id) + CHAR(9) + @recipients
EXEC msdb.dbo.sp_send_dbmail
@profile_name = @profile_name ,
@recipients = @recipients ,
@subject = @subject ,
@body_format = @body_format ,
@body = @body
UPDATE msdb.dbo.sysmail_mailitems
SET sent_status = 3
WHERE mailitem_id = @mailitem_id
END
CLOSE SYSMAIL_LOG_RESEND_CURSOR
DEALLOCATE SYSMAIL_LOG_RESEND_CURSOR
END
GO
Я знаю, что это не тот ответ, который вы хотите услышать, но я всегда пытаюсь отделить почтовую функцию. Я мог бы использовать триггер для порождения внешнего процесса, если отправка почты должна быть своевременной, но я позволил внешнему сценарию выполнить реальную работу по отправке почты. Таким образом MTA устраняет временные ошибки соединения, и мне не нужно беспокоиться о специальных алгоритмах бухгалтерского учета.