この特定の状況で 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' をバインドできませんでした。add 演算子では、データ型 varchar と date は互換性がありません。
明らかに、その変数を設定する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