У меня возникают проблемы с созданием триггера, который отправит электронное письмо, содержащее таблицу вставленных данных в список рассылки, когда устройство подключено к загрузчику IP, и данные отправляются в таблицу на SQL Server. Мне нужно выбрать дату, идентификатор загрузки и описание из самых последних записей (23–26 строк за одну загрузку), а затем отформатировать их в электронное письмо и отправить.
Я относительно новичок в SQL, поэтому не уверен, где мне нужно посмотреть, какую ошибку генерирует триггер. Ниже приведен блок кода, с которым я пытался работать. Любые предложения или советы будут оценены. Когда я запускаю оператор select и хранимую процедуру электронной почты вручную, все работает нормально. Как только я превращаю его в спусковой крючок, он выходит из строя.
CREATE TRIGGER [dbo].[Trg_Download]
ON [dbo].[DownloadData]
AFTER INSERT
AS
BEGIN
SET NOCOUNT ON;
DECLARE @DownloadID VARCHAR(7)
DECLARE @xml NVARCHAR(MAX)
DECLARE @body NVARCHAR(MAX)
SET @DownloadID = (SELECT TOP 1 downloadID
FROM inserted
ORDER BY downloadid DESC)
SET @xml = CAST((SELECT [Date] AS 'td','',[DownloadID] AS 'td','', [Description] AS 'td'
FROM inserted
WHERE [DownloadID] = @downloadID
ORDER BY Description
FOR XML PATH('tr'), ELEMENTS) AS NVARCHAR(MAX))
SET @body = '<html><body><H3>Line Clearout Summary</H3>
<table border = 1>
<tr>
<th> Date </th> <th> DownloadID </th> <th> Description </th></tr>'
SET @body = @body + @xml +'</table></body></html>'
EXEC msdb.dbo.sp_send_dbmail
@profile_name = N'DBMail',
@body = @body,
@body_format = HTML,
@recipients = N'[email protected]',
@subject = 'Line Clearout Summary'
END
Спасибо
Подумайте о том, чтобы поместить команду отправки электронной почты в сам код, который заполняет таблицу.
К сожалению, у меня нет разрешения на изменение кода, заполняющего таблицу.
Как сказал @ lad2025, не делайте этого; это может вызвать всевозможные проблемы. Например, если электронное письмо не может быть отправлено по какой-либо причине (возможно, ваш почтовый сервер не работает, или кто-то без разрешения на использование sp_send_dbmail
пытается выполнить INSERT
), то INSERT
выйдет из строя. Это не должно быть запланированным поведением. TRIGGER
- одно из последних мест, куда вы должны поместить логику для отправки электронной почты.
Триггер запускается в той же транзакции, что и код, вызвавший его срабатывание, поэтому добавьте этот код в свой вопрос. Я не вижу ничего явно неправильного в коде триггера. Также вы говорите, что это не работает, но вы не знаете, в чем ошибка. Как узнать об ошибке? Что вы имеете в виду под «не работает»?
У меня нет кода, который вызывает срабатывание триггера. Я знаю, что что-то не работает, потому что вся транзакция откатывается, когда я пытаюсь импортировать данные с помощью триггера в таблице. Думаю, это просто невозможно.
Если у вас нет разрешения на изменение кода самостоятельно, поговорите с кем-нибудь, кто может. Как видите, существует так много причин, по которым не поступать так, как вы просили, однако так мало причин, почему вам следует это сделать. Я уверен, что они тоже поймут причины и будут рады рассмотреть альтернативы или даже реализовать это в приложении.
Я уже пробовал попросить их сменить код. Их не интересует настройка кода в соответствии с тем, как мы реализуем систему. Я буду искать альтернативы без срабатывания триггера для выполнения этой задачи
По поводу комментариев «не делай этого»: Не делай этого таким образом. Вместо этого взгляните на Сервисный брокер (прочтите введение здесь). Это позволит вам ставить в очередь сообщения (а не сообщения электронной почты за просмотр, любое сообщение) для асинхронной обработки (какой-либо другой процедурой). Таким образом, ваш триггер не задержит и не прервет всю транзакцию. Если электронное письмо не может быть отправлено, сообщение может оставаться в очереди для последующих попыток.
Хотя я полностью согласен с тем, что вы не должны помещать эту логику «Отправить электронное письмо» в триггер, рассматривая свой вопрос как академический, я предлагаю вам обернуть текущий код триггера (от первого DECLARE
до последнего EXEC
) в блоке TRY..CATCH
. что может позволить вам регистрировать любую ошибку, возникающую в этом коде, а также предотвратить откат транзакции, не выдавая ошибку.
Между прочим, поскольку никто не предлагал конкретной альтернативы, я скажу вам, что мы реализуем такую логику с помощью задания агента, которое выполняется через регулярные промежутки времени и отправляет электронные письма в зависимости от того, какие строки были добавлены с момента последнего выполнения задания. . Вы можете либо добавить столбцы в таблицу DownloadData
, которая отслеживает, было ли отправлено электронное письмо, либо вы можете использовать триггер AFTER INSERT
для заполнения отдельной таблицы, которую задание обрабатывает как очередь электронной почты.
Спасибо. Я рассмотрю возможность использования агента задания для запуска задачи вместо триггера.