更改数据时的电子邮件触发器

时间:2011-05-11 12:48:08

标签: sql sql-server-2008

我创建了一个触发器,当字段Aantal发生更改时发送电子邮件,但问题是它不会将删除和插入的数据放在电子邮件正文中。 我被告知这是因为删除和插入包含多行。 请建议“获取包含已更改数据的行”的解决方案。

即时使用SQL Server 2008R2

CODE:

      --DE TRIGGERT--
ALTER TRIGGER [dbo].[RVABestellingenAantalWijzigenTrigger]
ON [dbo].[RVA_Bestellingen]  
AFTER UPDATE
AS
--Vars
DECLARE @body varchar(500)
DECLARE @BestellingID int
DECLARE @CategorieID int
DECLARE @SubCategorieID int
DECLARE @AantalOrigineel int
DECLARE @AantalNieuw int
DECLARE @LocatieNaam varchar(255)
DECLARE @ComponentNaam varchar(255)
DECLARE @CategorieNaam varchar(255)
DECLARE @SubCategorieNaam varchar(255)
DECLARE @Datum datetime

if update(Aantal) /*and (SELECT Datum FROM inserted) = cast(floor(cast(dateadd(day,1,getdate()) as float)) as datetime)  */ and   (convert(varchar,getdate(),108)>'11:00')
begin

    --Zetten aantallen
    SET @AantalOrigineel            = (SELECT Aantal FROM deleted)
    SET @AantalNieuw                = (SELECT Aantal FROM inserted) 
    SET @BestellingID               = (SELECT BestellingID FROM inserted)
    SET @CategorieID                = (SELECT CategorieID FROM inserted)    
    SET @SubCategorieID             = (SELECT SubCategorieID FROM inserted) 

    --Zetten locatienaam en componentnaam
    SELECT @LocatieNaam = ('RVA Aanpassingen Locatie: '+LocatieNaam), @ComponentNaam=OfficieleNaam, @Datum=Datum
    FROM RVA_Bestellingen r
    LEFT OUTER JOIN Locaties l on l.LocatieID = r.LocatieID
    LEFT OUTER JOIN Componenten c on c.ComponentID = r.ComponentID
    WHERE r.BestellingID = @BestellingID    


    SELECT @CategorieNaam = Categorie
    FROM RVA_HoofdCategorie
    WHERE HoofdCategorieID = @CategorieID   

    SELECT @SubCategorieNaam = Categorie
    FROM dbo.RVA_SubCategorie
    WHERE SubCategorieID = @SubCategorieID      

    --Zet boyd
    SET @body = (
                    SELECT 
                        'HoofdCategorie: ' + @CategorieNaam+ char(10)+char(13)
                        +'SubCategorie: ' + @SubCategorieNaam+ char(10)+char(13)
                        + 'Componentnaam: '
                        + @ComponentNaam + char(10)+char(13)
                        + 'Origineel aantal: '
                        + CAST(@AantalOrigineel as varchar(50) ) + char(10)+char(13)
                        + 'Nieuw aantal: '
                        + CAST(@AantalNieuw as varchar(50) ) + char(10)+char(13)
                        + 'Leverdatum: ' +
                        + convert(varchar(50),@Datum,105)                       
                )

    --Mailen naar Adeline
     EXEC master..xp_sendmail 
            @recipients = 'test@test.nl', 
            @message    = @body, 
            @subject    = @LocatieNaam
end

2 个答案:

答案 0 :(得分:4)

您了解触发器每批次触发而不是每行触发?这通常是一个坏主意。将数据转储到另一个表中,编写一个每分钟检查一次该表的作业并发送一封电子邮件

您希望触发器尽可能快,而不是发送电子邮件

另请参阅:Best Practice: Coding SQL Server triggers for multi-row operations

你的另一个选择(这也是一个坏主意)循环遍历触发器中已删除和插入的表格,并为每一行发送电子邮件

您应该使用sp_send_dbmail而不是xp_sendmail,因为您在2008年,xp_sendmail已被弃用

就像一个FYI

类似这样的事情

SET @BestellingID               = (SELECT BestellingID FROM inserted)
SET @CategorieID                = (SELECT CategorieID FROM inserted)    
SET @SubCategorieID             = (SELECT SubCategorieID FROM inserted)

可以通过1选择

完成
  SELECT    @BestellingID = BestellingID,
        @CategorieID = CategorieID,
        @SubCategorieID = SubCategorieID 
FROM inserted

无需执行3个查询...这对您无需帮助,因为您必须为多行编码,但只是为了向您展示您可以通过1选择分配多个变量

答案 1 :(得分:0)

由于您可以修改多行,因此无法仅获取已更改数据。

例如,如果执行以下操作:

UPDATE MyTable
SET Col2 = Col2 + 1

每行将Col2增加1。你想要哪一行你的例子?

您可以在选择中使用TOP 1子句将值分配给顶部的变量,但执行所需操作的唯一方法是使用WHILE循环或游标每行发送一封电子邮件,这可能是很多电子邮件。

此外,这通常是一种非常糟糕的做法,因为您的所有交易都将保留在此电子邮件程序中以触发每次更新/删除/插入。