2015-12-08 1 views
1

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

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

Как вы можете видеть, я попытался использовать значение таблицы для отправки в теме, но я получаю письмо с SQL Server Message в теме.

Еще одна вещь, которую я хочу добавить, - это запросить таблицу и проверить, есть ли в таблице INSERTED.USERID или нет, если она недоступна, то нет необходимости запускать триггер.

USE [Attendance] 
GO 
SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
ALTER TRIGGER [dbo].[after_insert_ATT_LOG] ON [dbo].[ATT_LOG] 
FOR INSERT 
AS 
BEGIN TRY 

DECLARE @PositionCode NVARCHAR(5), @FullNameE NVARCHAR(45), @FullNameE2 NVARCHAR(40), @Email NVARCHAR(50), @EDescription NVARCHAR(100), @ReportingToShortNo NVARCHAR(5), @ReportingtoFullNameE NVARCHAR(45), @ReportingEmail NVARCHAR(50) 

Select @PositionCode=ED.POsitionCode, @FullNameE=EP.FullNameE,@FullNameE2=ED.FullNameE, @Email=ED.Email, @EDescription=EP.EDescription, @ReportingToShortNo=EP.ReportingToShortNo, @ReportingtoFullNameE=EP.ReportingtoFullNameE, @ReportingEmail=(Select Email 
FROM HRSystem.dbo.employeedetails WHERE PositionCode= EP.ReportingToShortNo) FROM HRSystem.dbo.employeedetails ED, HRSystem.dbo.Position EP WHERE ED.PositionID = EP.PositionID AND ED.PositionCode = (Select INSERTED.USERID FROM INSERTED) COLLATE DATABASE_DEFAULT; 

EXEC msdb.dbo.sp_send_dbmail 
@recipients = '[email protected]', 
@profile_name = 'Alert', 
@subject = @FullNameE, 
@body = 'Test Alert'; 

END TRY 
BEGIN CATCH 

DECLARE @dummy int 
SET @dummy = 1 
END CATCH 
+1

Ваш триггер ** MAJOR ** недостаток в том, что вы, кажется, предположить, что это будет называться ** один раз в строке ** - это ** не ** случай. Триггер будет срабатывать ** один раз за оператор **, поэтому, если ваши инструкции 'INSERT' влияют на 25 строк, вы получите триггер, запущенный ** один раз **, но затем' Inserted' будет содержать 25 строк. Какой из этих 25 строк будет выбран ваш код? '(Выберите INSERTED.USERID FROM INSERTED)' - он не детерминирован, вы получите ** одну произвольную строку **, а все остальные игнорируются. Для этого нужно переписать триггер! –

+0

Также: триггер должен быть проворным, быстрым, крошечным ** - и он должен ** не содержать вещи, которые делают тяжелую работу, большую обработку или трудоемкие задачи, такие как отправка электронной почты. Это может потенциально привести к тайм-аутам в вашем коде, и это уверенный убийца любой производительности системы, который у вас есть. –

ответ

2

, как для второго концерна

Еще одна вещь, которую я хочу добавить, чтобы запросить таблицу и проверить, если INSERTED.USERID доступен в таблице или нет, если он не доступен, то нет необходимости запускать курок.

a FOR INSERT триггерные огни сразу после ввода строки. смысл, USERID Вы хотите найти обязательно в таблице ATT_LOG.

а также для первого выпуска. пожалуйста, попробуйте код T-SQL ниже:

CREATE TRIGGER [dbo].[after_insert_ATT_LOG] ON [dbo].[ATT_LOG] 
FOR INSERT 
AS 
BEGIN TRY 

DECLARE @PositionCode NVARCHAR(5), @FullNameE NVARCHAR(45), @FullNameE2 NVARCHAR(40), @Email NVARCHAR(50), @EDescription NVARCHAR(100), @ReportingToShortNo NVARCHAR(5), @ReportingtoFullNameE NVARCHAR(45), @ReportingEmail NVARCHAR(50) 

Select @PositionCode=ED.POsitionCode, @FullNameE=EP.FullNameE,@FullNameE2=ED.FullNameE 
    , @Email=ED.Email, @EDescription=EP.EDescription 
    , @ReportingToShortNo=EP.ReportingToShortNo 
    , @ReportingtoFullNameE=EP.ReportingtoFullNameE 
    , @ReportingEmail= 
     (Select Email 
     FROM HRSystem.dbo.employeedetails 
     WHERE PositionCode= EP.ReportingToShortNo) 
FROM HRSystem.dbo.employeedetails ED, HRSystem.dbo.Position EP 
WHERE ED.PositionID = EP.PositionID 
    AND ED.PositionCode = 
    (Select INSERTED.PositionCode FROM INSERTED) COLLATE DATABASE_DEFAULT; 

EXEC msdb.dbo.sp_send_dbmail 
@recipients = '[email protected]', 
@profile_name = 'Alert', 
@subject = @FullNameE, 
@body = 'Test Alert'; 

END TRY 
BEGIN CATCH 

DECLARE @dummy int 
SET @dummy = 1 
END CATCH 
+0

В коде нет изменений, он такой же, как и есть. – user3625561

+0

Я изменил эту строку '(выберите INSERTED.PositionCode FROM INSERTED) COLLATE DATABASE_DEFAULT;' вы использовали 'INSERTED.USERID' в своем. – t1t1an0

+0

В вставленной таблице нет кода позиции, userid - это поле для запроса. – user3625561

Смежные вопросы