sp_send_dbmail在AFTER UPDATE TRIGGER中使用动态SQL

时间:2013-09-05 14:16:29

标签: sql sql-server-2008

由于这是我第一次需要为这种特殊情况编写T-SQL,我希望有人可以查看我的T-SQL来检查错误。我有什么问题,我该如何解决?

CREATE TRIGGER SendConfirmationEmail
ON dbo.Appointments
AFTER UPDATE
AS
IF UPDATE(PersID)
BEGIN
--Declare and Set Dynamic SQL Variables
DECLARE @MsgBody NVARCHAR(MAX);
DECLARE @MsgDate DATE;
DECLARE @MsgTime TIME(0);
DECLARE @MsgSubject VARCHAR(50);
DECLARE @MsgRecipients NVARCHAR(MAX);
SELECT @MsgDate = (SELECT [Date] FROM [Appointments] WHERE inserted.PersID = Appointments.PersID)
SELECT @MsgTime = (SELECT [Time] FROM [Appointments] WHERE inserted.PersID = Appointments.PersID)
SET @MsgSubject = 'Appointment Confirmation'
SET @MsgBody = 'You are confirmed for a physical appointment on ' + @MsgDate + ' at ' + @MsgTime + '.'
SELECT @MsgRecipients = (SELECT [p.Email] FROM [Personnel].[dbo].[PData] as p JOIN [Physicals].[Appointments] AS ph ON p.PersID = ph.PersID WHERE inserted.PersID = Appointments.PersID)
--Execute the SP to send the confirmation e-mail
EXEC msdb.dbo.sp_send_dbmail @profile_name = 'Mail_Profile', @recipients = @MsgRecipients, @subject = @MsgSubject, @body = @MsgBody

当我尝试保存触发器时,我收到以下错误:

无法绑定多部分标识符“inserted.PersID”。 无法绑定多部分标识符“inserted.PersID”。 数据类型varchar和date在add运算符中不兼容。

显然,它不喜欢在select语句设置该变量中使用触发器虚拟“inserted”表。如何正确完成?基本上,我只想从与触发器发生的表不同的表中检索相应的值,并在此表的触发器中使用它。更简单地说,当更新PersID值时,我想从另一个表中获取有关该信息的信息,然后发送确认电子邮件。

解决方案:@Tobsey非常有帮助,对于遇到此问题的其他人,我已经包含了通过SSMS验证的代码的最终版本。

ALTER TRIGGER [dbo].[SendConfirmationEmail] 
ON [dbo].[Appointments]
AFTER UPDATE
AS
IF UPDATE(PersID)
BEGIN
--Declare and Set Dynamic SQL Variables
DECLARE @MsgBody NVARCHAR(MAX);
DECLARE @MsgDate DATE;
DECLARE @MsgTime TIME(0);
DECLARE @MsgSubject VARCHAR(50);
DECLARE @MsgRecipients NVARCHAR(MAX);
SELECT @MsgDate = (SELECT ph.Date FROM [Physicals].[dbo].[Appointments] AS ph INNER JOIN Inserted ON inserted.PersID = ph.PersID WHERE inserted.PersID = ph.PersID)
SELECT @MsgTime = (SELECT ph.Time FROM [Physicals].[dbo].[Appointments] AS ph INNER JOIN Inserted ON inserted.PersID = ph.PersID WHERE inserted.PersID = ph.PersID)
SET @MsgSubject = 'Appointment Confirmation'
SET @MsgBody = 'You are confirmed for a physical appointment on ' + CAST(@MsgDate AS varchar) + ' at ' + CAST(@MsgTime AS varchar) + '.'
SELECT @MsgRecipients = (SELECT p.Email FROM [Personnel].[dbo].[PData] as p INNER JOIN [Physicals].[dbo].[Appointments] AS ph ON p.PersID = ph.PersID INNER JOIN Inserted ON inserted.PersID = ph.PersID WHERE inserted.PersID = ph.PersID)
--Execute the SP to send the confirmation e-mail
EXEC msdb.dbo.sp_send_dbmail @profile_name = 'Mail_Profile', @recipients = @MsgRecipients, @subject = @MsgSubject, @body = @MsgBody
END

1 个答案:

答案 0 :(得分:1)

您还需要加入Inserted表。您不能只在WHERE子句中使用它:

SELECT @MsgDate = 
    (SELECT [Date] FROM 
    [Appointments] 
    INNER JOIN Inserted ON inserted.PersID = Appointments.PersID)

SELECT @MsgTime = 
    (SELECT [Time] FROM 
    [Appointments] 
    INNER JOIN Inserted ON inserted.PersID = Appointments.PersID)

SELECT @MsgRecipients = 
    (SELECT [p.Email] FROM 
    [Personnel].[dbo].[PData] as p 
    INNER JOIN [Physicals].[Appointments] AS ph ON p.PersID = ph.PersID 
    INNER JOIN Inserted ON inserted.PersID = ph.PersID)

您还需要将datetime类型转换为varchar才能将它们连接起来。