2013-09-05 90 views
0

因爲這是我第一次需要爲這種特殊情況編寫T-SQL,所以我希望有人可以查看我的T-SQL來檢查錯誤。我弄錯了什麼,我該如何解決它?帶有動態SQL的sp_send_dbmail,其中包含AFTER UPDATE TRIGGER

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和日期在add運算符中不兼容。

很明顯,它不喜歡在設置該變量的select語句中使用觸發虛擬「插入」表。這將如何正確完成?基本上,我只想從與觸發器不同的表中檢索相應的值,並將其用於此表的觸發器中。更簡單地說,當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

您還需要加入插入的表格。你不能只是使用它的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,以將它們連接起來。

+0

非常感謝@Tobsey。一個簡單的問題:當你說我需要將'date'和'time'類型轉換爲'varchar'時,我在[link](http://technet.microsoft.com/en-us/library/ ms187928(v = sql.105).aspx),並注意到它在那裏調用了這個隱式轉換,並指出CAST在這裏不是必需的。你是指這個規則的例外,還是在這裏發生了一些不同的事情? – RGS