Триггер электронной почты SQL Server при вставке данных в таблицу не работает

У меня возникают проблемы с созданием триггера, который отправит электронное письмо, содержащее таблицу вставленных данных в список рассылки, когда устройство подключено к загрузчику 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

Спасибо

Просто не делай этого.
Lukasz Szozda 01.05.2018 20:02

Подумайте о том, чтобы поместить команду отправки электронной почты в сам код, который заполняет таблицу.

Daniel Marcus 01.05.2018 20:09

К сожалению, у меня нет разрешения на изменение кода, заполняющего таблицу.

J M 01.05.2018 20:19

Как сказал @ lad2025, не делайте этого; это может вызвать всевозможные проблемы. Например, если электронное письмо не может быть отправлено по какой-либо причине (возможно, ваш почтовый сервер не работает, или кто-то без разрешения на использование sp_send_dbmail пытается выполнить INSERT), то INSERT выйдет из строя. Это не должно быть запланированным поведением. TRIGGER - одно из последних мест, куда вы должны поместить логику для отправки электронной почты.

Larnu 01.05.2018 20:39

Триггер запускается в той же транзакции, что и код, вызвавший его срабатывание, поэтому добавьте этот код в свой вопрос. Я не вижу ничего явно неправильного в коде триггера. Также вы говорите, что это не работает, но вы не знаете, в чем ошибка. Как узнать об ошибке? Что вы имеете в виду под «не работает»?

Tab Alleman 01.05.2018 20:51

У меня нет кода, который вызывает срабатывание триггера. Я знаю, что что-то не работает, потому что вся транзакция откатывается, когда я пытаюсь импортировать данные с помощью триггера в таблице. Думаю, это просто невозможно.

J M 01.05.2018 21:01

Если у вас нет разрешения на изменение кода самостоятельно, поговорите с кем-нибудь, кто может. Как видите, существует так много причин, по которым не поступать так, как вы просили, однако так мало причин, почему вам следует это сделать. Я уверен, что они тоже поймут причины и будут рады рассмотреть альтернативы или даже реализовать это в приложении.

Larnu 01.05.2018 21:03

Я уже пробовал попросить их сменить код. Их не интересует настройка кода в соответствии с тем, как мы реализуем систему. Я буду искать альтернативы без срабатывания триггера для выполнения этой задачи

J M 01.05.2018 22:13

По поводу комментариев «не делай этого»: Не делай этого таким образом. Вместо этого взгляните на Сервисный брокер (прочтите введение здесь). Это позволит вам ставить в очередь сообщения (а не сообщения электронной почты за просмотр, любое сообщение) для асинхронной обработки (какой-либо другой процедурой). Таким образом, ваш триггер не задержит и не прервет всю транзакцию. Если электронное письмо не может быть отправлено, сообщение может оставаться в очереди для последующих попыток.

sticky bit 02.05.2018 00:32
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
1
9
74
1

Ответы 1

Хотя я полностью согласен с тем, что вы не должны помещать эту логику «Отправить электронное письмо» в триггер, рассматривая свой вопрос как академический, я предлагаю вам обернуть текущий код триггера (от первого DECLARE до последнего EXEC) в блоке TRY..CATCH. что может позволить вам регистрировать любую ошибку, возникающую в этом коде, а также предотвратить откат транзакции, не выдавая ошибку.

Между прочим, поскольку никто не предлагал конкретной альтернативы, я скажу вам, что мы реализуем такую ​​логику с помощью задания агента, которое выполняется через регулярные промежутки времени и отправляет электронные письма в зависимости от того, какие строки были добавлены с момента последнего выполнения задания. . Вы можете либо добавить столбцы в таблицу DownloadData, которая отслеживает, было ли отправлено электронное письмо, либо вы можете использовать триггер AFTER INSERT для заполнения отдельной таблицы, которую задание обрабатывает как очередь электронной почты.

Спасибо. Я рассмотрю возможность использования агента задания для запуска задачи вместо триггера.

J M 01.05.2018 22:10

Другие вопросы по теме