Sql 触发事件中的电子邮件查询信息
我试图创建一个触发器,每当用户插入一个特定值时,它都会通过电子邮件发送与该值相关的信息(另外4列) 我不知道什么是最好的选择,我试过: 步骤#1:在触发器运行时创建存储过程Sql 触发事件中的电子邮件查询信息,sql,sql-server,tsql,stored-procedures,triggers,Sql,Sql Server,Tsql,Stored Procedures,Triggers,我试图创建一个触发器,每当用户插入一个特定值时,它都会通过电子邮件发送与该值相关的信息(另外4列) 我不知道什么是最好的选择,我试过: 步骤#1:在触发器运行时创建存储过程 CREATE PROCEDURE NewVendorAlert AS BEGIN DECLARE @BODY NVARCHAR(800) SET @body = N'Hello,' + '<br>' + '<br>' + N'Please see the attachment
CREATE PROCEDURE NewVendorAlert
AS
BEGIN
DECLARE @BODY NVARCHAR(800)
SET @body = N'Hello,' + '<br>' + '<br>' +
N'Please see the attachment of the new vendor information' + '<br>' + '<br>' +
N'Sincerely,' + '<br>' + '<br>' +
N'Process Improvement Department'
EXEC msdb.dbo.sp_send_dbmail
@profile_name = 'SQLMail',
@recipients = 'gmolina@allenflavors.com',
@subject = 'New Vendor Entered',
@query = N'SELECT TOP 1 LTRIM(RTRIM(VENDORID)) AS [VENDOR ID],
LTRIM(RTRIM(VENDNAME)) AS [VENDOR NAME],
CONCAT(LTRIM(RTRIM(ADDRESS1)),'' '', LTRIM(RTRIM(ADDRESS2)), '' '', LTRIM(RTRIM(ADDRESS3)) ) AS [ADDRESS],
LTRIM(RTRIM(STATE)) [STATE],
LTRIM(RTRIM(COUNTRY)) [COUNTRY],
MAX(LTRIM(RTRIM(CREATDDT))) AS [DATE ENTERED]
FROM [ALLEN].[dbo].[PM00200]
GROUP BY VENDORID,CREATDDT, VENDNAME, ADDRESS1, ADDRESS2, ADDRESS3, STATE, COUNTRY
ORDER BY CREATDDT DESC',
@attach_query_result_as_file = 1,
@query_attachment_filename = 'New Vendor.csv',
@query_result_separator = ' ',
@query_result_no_padding = 1,
@exclude_query_output = 1,
@append_query_error = 0,
@query_result_header = 1,
@body = @body,
@query_result_width = 32767,
@importance = 'HIGH',
@body_format = 'HTML'
END
我尝试过其他事情,如果我走的是正确的道路,或者有其他选择,我会很感激的
谢谢大家! 如前所述,您希望避免在触发器中执行任何缓慢的操作,并且联系SMTP服务器可能非常缓慢。发送电子邮件时,最好的解决方案是将条目放入队列表中,并让服务进程处理队列并发送电子邮件 但是,有时您会发现自己必须处理插入的表RBAR,在这种情况下,您需要遍历所有记录,下面是一个如何执行此操作的示例
CREATE TRIGGER [dbo].[NewVendorInformation]
ON [dbo].[PM00200]
AFTER INSERT
AS
BEGIN
SET NOCOUNT ON;
DECLARE @VENDORID char(15);
SELECT VENDORID
INTO #PM00200_Temp
FROM Inserted
GROUP BY VENDORID;
WHILE EXISTS (SELECT 1 FROM #PM00200_Temp) BEGIN
SELECT TOP 1 @VENDORID = VENDORID FROM #PM00200_Temp;
EXEC NewVendorAlert @VENDORID;
DELETE FROM #PM00200_Temp WHERE VENDORID = @VENDORID;
END;
END;
你犯了一个典型的触发器101错误,假设插入的
只有一条记录。。。当它可能有0-N时。如果这确实是处理它的最佳方法,那么您需要在插入的
中的每一行循环一次调用SP的记录。如果你收到一个错误,一定要发布它,这样我们就可以看到它是什么。另外:我强烈建议不要从触发器内部发送电子邮件(这可能需要相当长的时间)。触发器在引发它的语句的上下文中运行,并延长该语句的事务时间,直到触发器完成为止。你应该在触发器中只做很少的工作——而且最肯定的是不要呼叫外部服务或发送电子邮件……事实上,我并没有给出一个错误,因为当我插入一条记录时,它需要永远执行。我只是终止了阻塞会话ID。所以,当我插入插入值时,你们会建议用电子邮件将Select语句中的信息发送给我(在存储过程中),这有点棘手。因为我用唯一的触发器编写了另一个代码,但我需要声明其他变量,问题是当我插入另一个值时,我选择的值不是执行触发器的值。这就是为什么我选择了这个选项。这非常有帮助,谢谢@DaleK,我运行了您编写的触发器,但它给我带来了一个错误:Msg 8146,级别16,状态1,过程NewVendorAlert,第0行[Batch Start Line 24]过程NewVendorAlert没有参数,并且提供了参数。语句已终止。
这很奇怪,因为您在存储过程中声明了一个参数,如果我取出该参数,情况也是如此。有什么想法吗?@GabrielMolina这个错误是不言自明的。。。我假设您希望在proc中包含VendorID,但是您的proc在编写时不接受VendorID。因此,要么在SP中添加一个参数,要么在触发器中不需要VendorID,在这种情况下,如果删除VendorID内容,原始触发器就会工作。
CREATE TRIGGER [dbo].[NewVendorInformation]
ON [dbo].[PM00200]
AFTER INSERT
AS
BEGIN
SET NOCOUNT ON;
DECLARE @VENDORID char(15);
SELECT VENDORID
INTO #PM00200_Temp
FROM Inserted
GROUP BY VENDORID;
WHILE EXISTS (SELECT 1 FROM #PM00200_Temp) BEGIN
SELECT TOP 1 @VENDORID = VENDORID FROM #PM00200_Temp;
EXEC NewVendorAlert @VENDORID;
DELETE FROM #PM00200_Temp WHERE VENDORID = @VENDORID;
END;
END;