0

由于这是我第一次需要为这种特殊情况编写 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 运算符中不兼容。

显然,它不喜欢在设置该变量的选择语句中使用触发器虚拟“插入”表。这将如何正确完成?基本上,我只想从与触发发生的表不同的表中检索相应的值,并在该表的触发器中使用它。更简单地说,当 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
4

1 回答 1

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为以连接它们。

于 2013-09-05T14:33:00.847 回答