来自多个 table 的电子邮件数据与插入的 table 连接
Email data from several tables which is joined with inserted table
我有四张表:
Activity:
ActivityID(PK) ActivityName CustomerID(FK) UserId(FK)
1 Lead Gen 1st 50 U1
2 Lead Gen 2nd 60 U2
客户:
CustomerID(PK) CustomerNumber CustomerName
50 C0150 cust50 ltd
60 C0160 cust60 ltd
用户:
UserID(PK) UserName Email
U1 Mr. X X@cat.com
U2 Mr. Y Y@cat.com
用户Activity:
UserActivityID(PK) UserID(FK) ActivityID(FK)
888 U1 1
889 U2 2
如果在 Activity
Table(SQL 服务器 2008-R2)。
电子邮件正文应包含 ActivityId
、ActivityName
、CustomerNumber
和 CustomerName
。
触发器必须执行上述操作,结果在电子邮件中应如下所示:
ActivityID:1, ActivityName:Lead Gen 1st created for CustomerNumber: C0150 & CustomerName: cust50 ltd
这是我的代码:
CREATE TRIGGER [dbo].[Activity_Insert_Mail_Notification]
ON [dbo].[Activity]
AFTER INSERT
AS
BEGIN
DECLARE @ActivityID varchar(2000)
DECLARE @ActivityName varchar (2000)
Select @ActivityID=inserted.ActivityID,@ActivityName=inserted.ActivityName
From inserted
DECLARE @CustomerNo varchar(2000)
DECLARE @CustomerName varchar(2000)
Select @CustomerNo = B.[CustomerNumber]
,@CustomerName= B.[CustomerName]
from [dbo].[Activity] A
inner join [dbo].[Customer] B
on A.[CustomerID]=B.[CustomerID]
DECLARE @email VARCHAR(2000)
SELECT @email = RTRIM(U.[Email]) + ';'
FROM [dbo].[Activity] A
left join [dbo].[UserActivity] UA
inner join [dbo].[User] U
on UA.[UserID]=U.[UserID]
on A.[ActivityID]=UA.[ActivityID]
WHERE U.[Email]<> ''
DECLARE @content varchar (2000)
= 'ActivityID:' + @ActivityId + ' '
+ ',ActivityName:' + @ActivityName + ' '
+ 'has been created for' + 'CustomerNumber: ' + @CustomerNo
+ ' ' + '&CustomerName: ' + @CustomerName
EXEC msdb.dbo.sp_send_dbmail
@profile_name = 'LEADNOTIFY'
,@recipients = @email
,@subject = 'New Lead Found'
,@body = @content
,@importance ='HIGH'
END
问题出在我的代码中,我无法从相应的表中正确获取客户数据和电子邮件。
我在下面编写了一些代码,这些代码将遍历所有受影响的行并为每个行发送一封电子邮件。
但是在您阅读之前,我强烈建议(正如@HABO 评论的那样)使用不同的方法。触发器适用于某些任务,但在使用触发器时需要牢记 2 个关键事项:
- 确保任何开发系统的人都清楚存在触发器 - 作为开发人员,没有什么比在看似简单的 CRUD 操作上神奇地发生的事情更糟糕的了。
- 尽可能快地执行您在触发器中执行的任何操作,因为您持有的锁不仅影响当前会话,而且很容易影响其他用户。因此,理想情况下,您希望执行基于集合的操作,而不是 RBAR(逐行逐行)操作。
在触发器内发送电子邮件是一件很糟糕的事情,因为被迫等待 SMTP 服务器响应的情况并不少见。如果您希望触发电子邮件,更好的方法是使用触发器将电子邮件数据插入队列 table,然后在其他地方提供服务,使这些电子邮件出列并发送。
除此之外,以下代码显示了一种在您要执行 RBAR 操作时处理 Inserted
pseudo-table 的方法。因为在 SQL 服务器中,Inserted
伪 table(和 Deleted
伪 table)将包含受操作影响的行数,即 0- N.我也希望加入你们的 table 以正确获取所需的信息。
CREATE TRIGGER [dbo].[Activity_Insert_Mail_Notification]
ON [dbo].[Activity]
AFTER INSERT
AS
BEGIN
SET NOCOUNT ON;
DECLARE @ActivityID VARCHAR(2000), @ActivityName VARCHAR(2000), @CustomerNo VARCHAR(2000), @CustomerName VARCHAR(2000), @Email VARCHAR(2000), @Content VARCHAR(2000);
-- Get all the relevant information into a temp table
SELECT ActivityID, ActivityName, C.CustomerNumber, C.CustomerName, RTRIM(U.[Email]) + ';' Email, CONVERT(BIT, 0) Handled
INTO #ActivityTriggerTemp
FROM Inserted I
INNER JOIN Customer C on C.CustomerID = I.CustomerID
INNER JOIN UserActivity UA on UA.ActivityID = I.ActivityID
INNER JOIN [USER] U on U.UserID = UA.UserID;
-- Loop through the temp table sending an email for each row, then setting the row as 'handled' to avoid sending it again.
WHILE EXISTS (SELECT 1 FROM #ActivityTriggerTemp WHERE Handled = 0) BEGIN
SELECT TOP 1 @ActivityID = ActivityID, @ActivityName = ActivityName, @CustomerNumber = CustomerNumber, @CustomerName = CustomerName, @Email = Email
FROM #ActivityTriggerTemp
WHERE Handled = 0;
-- Build the body of the email
set @Content = 'ActivityID:' + @ActivityId + ' '
+ ',ActivityName:' + @ActivityName + ' '
+ 'has been created for' + 'CustomerNumber: ' + @CustomerNo
+ ' ' + '&CustomerName: ' + @CustomerName;
-- Send the email
EXEC msdb.dbo.sp_send_dbmail
@profile_name = 'LEADNOTIFY'
, @recipients = @Email
, @subject = 'New Lead Found'
, @body = @Content
, @importance ='HIGH';
UPDATE #ActivityTriggerTemp SET
Handled = 1
WHERE ActivityID = @ActivityID AND ActivityName = @ActivityName AND CustomerNumber = @CustomerNumber AND CustomerName = @CustomerName AND Email = @Email;
END;
END
我有四张表:
Activity:
ActivityID(PK) ActivityName CustomerID(FK) UserId(FK)
1 Lead Gen 1st 50 U1
2 Lead Gen 2nd 60 U2
客户:
CustomerID(PK) CustomerNumber CustomerName
50 C0150 cust50 ltd
60 C0160 cust60 ltd
用户:
UserID(PK) UserName Email
U1 Mr. X X@cat.com
U2 Mr. Y Y@cat.com
用户Activity:
UserActivityID(PK) UserID(FK) ActivityID(FK)
888 U1 1
889 U2 2
如果在 Activity
Table(SQL 服务器 2008-R2)。
电子邮件正文应包含 ActivityId
、ActivityName
、CustomerNumber
和 CustomerName
。
触发器必须执行上述操作,结果在电子邮件中应如下所示:
ActivityID:1, ActivityName:Lead Gen 1st created for CustomerNumber: C0150 & CustomerName: cust50 ltd
这是我的代码:
CREATE TRIGGER [dbo].[Activity_Insert_Mail_Notification]
ON [dbo].[Activity]
AFTER INSERT
AS
BEGIN
DECLARE @ActivityID varchar(2000)
DECLARE @ActivityName varchar (2000)
Select @ActivityID=inserted.ActivityID,@ActivityName=inserted.ActivityName
From inserted
DECLARE @CustomerNo varchar(2000)
DECLARE @CustomerName varchar(2000)
Select @CustomerNo = B.[CustomerNumber]
,@CustomerName= B.[CustomerName]
from [dbo].[Activity] A
inner join [dbo].[Customer] B
on A.[CustomerID]=B.[CustomerID]
DECLARE @email VARCHAR(2000)
SELECT @email = RTRIM(U.[Email]) + ';'
FROM [dbo].[Activity] A
left join [dbo].[UserActivity] UA
inner join [dbo].[User] U
on UA.[UserID]=U.[UserID]
on A.[ActivityID]=UA.[ActivityID]
WHERE U.[Email]<> ''
DECLARE @content varchar (2000)
= 'ActivityID:' + @ActivityId + ' '
+ ',ActivityName:' + @ActivityName + ' '
+ 'has been created for' + 'CustomerNumber: ' + @CustomerNo
+ ' ' + '&CustomerName: ' + @CustomerName
EXEC msdb.dbo.sp_send_dbmail
@profile_name = 'LEADNOTIFY'
,@recipients = @email
,@subject = 'New Lead Found'
,@body = @content
,@importance ='HIGH'
END
问题出在我的代码中,我无法从相应的表中正确获取客户数据和电子邮件。
我在下面编写了一些代码,这些代码将遍历所有受影响的行并为每个行发送一封电子邮件。
但是在您阅读之前,我强烈建议(正如@HABO 评论的那样)使用不同的方法。触发器适用于某些任务,但在使用触发器时需要牢记 2 个关键事项:
- 确保任何开发系统的人都清楚存在触发器 - 作为开发人员,没有什么比在看似简单的 CRUD 操作上神奇地发生的事情更糟糕的了。
- 尽可能快地执行您在触发器中执行的任何操作,因为您持有的锁不仅影响当前会话,而且很容易影响其他用户。因此,理想情况下,您希望执行基于集合的操作,而不是 RBAR(逐行逐行)操作。
在触发器内发送电子邮件是一件很糟糕的事情,因为被迫等待 SMTP 服务器响应的情况并不少见。如果您希望触发电子邮件,更好的方法是使用触发器将电子邮件数据插入队列 table,然后在其他地方提供服务,使这些电子邮件出列并发送。
除此之外,以下代码显示了一种在您要执行 RBAR 操作时处理 Inserted
pseudo-table 的方法。因为在 SQL 服务器中,Inserted
伪 table(和 Deleted
伪 table)将包含受操作影响的行数,即 0- N.我也希望加入你们的 table 以正确获取所需的信息。
CREATE TRIGGER [dbo].[Activity_Insert_Mail_Notification]
ON [dbo].[Activity]
AFTER INSERT
AS
BEGIN
SET NOCOUNT ON;
DECLARE @ActivityID VARCHAR(2000), @ActivityName VARCHAR(2000), @CustomerNo VARCHAR(2000), @CustomerName VARCHAR(2000), @Email VARCHAR(2000), @Content VARCHAR(2000);
-- Get all the relevant information into a temp table
SELECT ActivityID, ActivityName, C.CustomerNumber, C.CustomerName, RTRIM(U.[Email]) + ';' Email, CONVERT(BIT, 0) Handled
INTO #ActivityTriggerTemp
FROM Inserted I
INNER JOIN Customer C on C.CustomerID = I.CustomerID
INNER JOIN UserActivity UA on UA.ActivityID = I.ActivityID
INNER JOIN [USER] U on U.UserID = UA.UserID;
-- Loop through the temp table sending an email for each row, then setting the row as 'handled' to avoid sending it again.
WHILE EXISTS (SELECT 1 FROM #ActivityTriggerTemp WHERE Handled = 0) BEGIN
SELECT TOP 1 @ActivityID = ActivityID, @ActivityName = ActivityName, @CustomerNumber = CustomerNumber, @CustomerName = CustomerName, @Email = Email
FROM #ActivityTriggerTemp
WHERE Handled = 0;
-- Build the body of the email
set @Content = 'ActivityID:' + @ActivityId + ' '
+ ',ActivityName:' + @ActivityName + ' '
+ 'has been created for' + 'CustomerNumber: ' + @CustomerNo
+ ' ' + '&CustomerName: ' + @CustomerName;
-- Send the email
EXEC msdb.dbo.sp_send_dbmail
@profile_name = 'LEADNOTIFY'
, @recipients = @Email
, @subject = 'New Lead Found'
, @body = @Content
, @importance ='HIGH';
UPDATE #ActivityTriggerTemp SET
Handled = 1
WHERE ActivityID = @ActivityID AND ActivityName = @ActivityName AND CustomerNumber = @CustomerNumber AND CustomerName = @CustomerName AND Email = @Email;
END;
END