SPROC 完成执行后如何触发触发器?

Posted

技术标签:

【中文标题】SPROC 完成执行后如何触发触发器?【英文标题】:How to fire a trigger after the SPROC has completed execution? 【发布时间】:2014-06-20 20:06:23 【问题描述】:

我编写了一个触发器,一旦执行 INSERT 行就会发送电子邮件。

ALTER TRIGGER TR_SendMailOnDataRequest
      ON DataRequest
AFTER INSERT
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE 
        @DR_Id INT,
        @DR_FullName VARCHAR(200),
        @DR_Email VARCHAR(200),
        @DR_Phone VARCHAR(20),
        @UT_Name VARCHAR(50),
        @DR_UserTypeOther VARCHAR(50) = NULL,
        @D_Name VARCHAR(200),
        @DR_RequestDate DATETIME,
        @UF_LinkedFiles VARCHAR(MAX),
        @DRN_Names VARCHAR(200),
        @DR_Description VARCHAR(1200),
        @DR_CreatedOn DATETIME,
        @analystMailList VARCHAR(MAX),
        @tablehtml NVARCHAR(MAX),
        @downloadLink VARCHAR(MAX) = N'NONE'

    SELECT @DR_Id = MAX(DR_Id) FROM dbo.DataRequest

    SELECT 
        @DR_FullName = DR_FullName,
        @DR_Email = DR_Email,
        @DR_Phone = DR_Phone,
        @UT_Name = UT_Name,
        @DR_UserTypeOther = DR_UserTypeOther,
        @D_Name = D_Name,
        @DR_RequestDate = DR_RequestDate,
        @UF_LinkedFiles = UF_LinkedFiles,
        @DRN_Names = DRN_Names,
        @DR_Description = DR_Description,
        @DR_CreatedOn = DR_CreatedOn
    FROM
        dbo.FN_GetDataRequest(@DR_Id)

    SELECT @analystMailList = dbo.FN_GetAnalystsMailList()

    IF (LEN(@UF_LinkedFiles) > 0)
    BEGIN
        SET @downloadLink = N'<a href="http://localhost:8500/workrequest/index.cfm?event=downloads.index&id=' + CAST(@DR_Id AS VARCHAR(10)) + N'&k='+ SUBSTRING(master.dbo.fn_varbintohexstr(HashBytes('SHA', ':be9[Dcv9wF~W!?xx4JO0OXLbZ@0p4+[~z0dO|:U,OF!13^xZb')), 3, 32) + N'">Downloads</a>'
    END

    SET @tableHTML =
        N'<H1>Data Request</H1>' +
        N'<UL>' +
        N'<LI>Full Name: ' + @UF_LinkedFiles + N'</LI>' +
        N'<LI>Email: ' + @DR_Email + N'</LI>' +
        N'<LI>Phone: ' + CAST(@DR_Phone AS VARCHAR(20)) + N'</LI>' +
        N'<LI>User Type: ' + @UT_Name + N'</LI>' +
        N'<LI>User Type Other: ' + COALESCE(@DR_UserTypeOther, N'NONE') + N'</LI>' +
        N'<LI>Reuest Date: ' + CONVERT(VARCHAR(20), @DR_RequestDate, 107) + N'</LI>' +
        N'<LI>Downloads: ' + @downloadLink + N'</LI>' +
        N'</UL>';

    BEGIN
        EXEC msdb.dbo.sp_send_dbmail 
            @profile_name = 'Example',
            @recipients = 'John Doe<jdoe@example>',
            --@recipients = @analystMailList,
            @reply_to = @DR_Email,
            @subject = 'Email Test',
            @body_format = 'HTML',
            @body = @tableHtml
    END
END
GO

当对表 DataRequest 执行 ROW INSERT 操作时,会触发上述触发器。在行插入操作之后,我将 INSERT 操作之后生成的 IDENTITY 元素用作外键,并在不同的表中插入其他值。最后,我使用两个表中的值并创建要发送的电子邮件。

我没有从其他表中获取值(例如 @UF_LinkedFiles),所以我意识到 TRIGGERINSERT 之后被触发FIRST 表中但在 SECOND 表中的 INSERT 之前,因此在 SENDING EMAIL 时没有可用值>.

那么我如何确保只有在执行多个表中的所有 INSERT 活动的 SPROC 完成事务之后才触发 TRIGGER

这是表格图 -

【问题讨论】:

第二个表也需要一个触发器。 第二个表中有多个条目,因此触发器将被多次触发。还有第三个表,我在其中插入值。 如果您的 SP 在两个表上都插入,那么您可以在 table2 上定义触发器,而不是在 table1 上定义它。这样,它将确保两个表上的插入都已完成,然后触发触发器。但是,您还必须确保插入确实在两个表上成功发生,或者根本没有使用事务范围。 这...SELECT @DR_Id = MAX(DR_Id) FROM dbo.DataRequest 在插入多行时会给您带来问题。查看inserted 表。它包含您所有的新数据,无需返回 DataRequest 表。 另外,请阅读并留意@JiggsJedi 的评论。触发器每次插入“触发”一次(不是每个插入行一次)。 msdn.microsoft.com/en-us/library/ms191300(v=sql.105).aspx 【参考方案1】:

我没有使用触发器,而是在插入行的 SPROC 中包含了 EMAIL SENDING 代码。

【讨论】:

【参考方案2】:

不确定这是否是您的情况,因为您没有解释表之间的行为如何。但我有一个场景,我尝试在一系列插入期间执行SELECT,但由于事务尚未完成,我找不到该行。

我所做的是创建一个额外的表

tblProgress
    id integer,
    fieldA integer,
    fieldB integer,
    fieldC integer

因此,如果您有 3 个表 TableA、TableB 和 TableC,每个表将有一个 INSERT 触发器并会执行一些工作,然后访问 tblProgress。

TableA 创建一行 TableB 和 TableC 更新。

然后 tblProgress 也将有一个 AFTER UPDATE 触发器,您可以在其中验证所有 3 个字段都有 NOT NULL

当您拥有所有 3 个值时,您可以发送电子邮件。

【讨论】:

以上是关于SPROC 完成执行后如何触发触发器?的主要内容,如果未能解决你的问题,请参考以下文章

Sql触发器是同步还是异步?

完成表中的数据插入后如何触发触发器

从 tableView 中选择项目时触发另一个函数后执行函数

承诺完成后触发 $ngAnimate 进入

SQL Server——触发器

在jq中,当触发点击事件后,在此事件没完成之前,不能再触发点击事件,在事件完成后才能再次点击,该怎么弄