Sql 后触发器与联接表

Sql 后触发器与联接表,sql,sql-server,tsql,triggers,inner-join,Sql,Sql Server,Tsql,Triggers,Inner Join,任务:创建一个AFTER触发器来完成一个连接条件。当创建一些记录时,触发器将位于表_1中。同时,表2有一个公共列,其中有一些条件需要的参数 每次应发送表2中的结果1和状态3以及警报时 -- QUERY WITH JOIN TABLE_1 ON TABLE_2 -- MOCK TABLE -- Table_1 as A | Table_2 as B A.LotCode | A.LineNumber | B.Result | B.Status 00000

任务:创建一个AFTER触发器来完成一个连接条件。当创建一些记录时,触发器将位于表_1中。同时,表2有一个公共列,其中有一些条件需要的参数

每次应发送表2中的结果1和状态3以及警报时

-- QUERY WITH JOIN TABLE_1 ON TABLE_2

-- MOCK TABLE 

-- Table_1 as A  |    Table_2 as B

   A.LotCode | A.LineNumber  | B.Result  |  B.Status 

    00000    |   xxxx        |   1       |   3
    00001    |   xxxx        |   2       |   4

-- The LotCode 00001 should send it through email because satisfy the condition 

下面介绍如何处理插入的
可能有多行这一事实。对于触发器来说,这确实不是理想的行为,因为您必须处理结果RBAR(一行接一行),这本身就很慢,更不用说发送电子邮件了

CREATE TRIGGER FullfillOrderQCResult
ON Table_1
AFTER INSERT
AS
BEGIN
    SET NOCOUNT ON;

    -----DECLARE VARIABLES-----

    DECLARE @ACTIONPEFORMED varchar(max), @Id int;

    SELECT A.LotCode, A.LineNumber, CONVERT(bit, 0) Done, IDENTITY(int) id -- Use your own id if you have one, just need to uniquely identify each row.
    INTO #FullfillOrderQCResult_temp
    FROM Inserted AS A
    INNER JOIN Table_2 AS B ON A.LotCode = B.DocumentID2
    WHERE B.Result <> 1 and B.[Status] <> 3;

    WHILE EXISTS (SELECT 1 FROM #FullfillOrderQCResult_temp WHERE Done = 0) BEGIN
        SELECT TOP 1 @Id = id, @ACTIONPEFORMED = 
            N'Hello, ' + '<br>' + '<br>'
            + N'The following LOT NUMBER: ' + LotCode + ' has not been approved for this Item: ' + LineNumber
        FROM #FullfillOrderQCResult_temp
        WHERE Done = 0;

        EXEC MSDB.DBO.SP_SEND_DBMAIL
            @PROFILE_NAME = 'SQLMail',
            @RECIPIENTS = 'TEST@gmail.com',
            @SUBJECT = 'LOT NON-Approved',
            @BODY = @ACTIONPEFORMED,
            @IMPORTANCE = 'HIGH',
            @BODY_FORMAT = 'HTML';

        UPDATE #FullfillOrderQCResult_temp SET Done = 1 WHERE id = @Id;
    END;
END;

下面介绍如何处理插入的
可能有多行这一事实。对于触发器来说,这确实不是理想的行为,因为您必须处理结果RBAR(一行接一行),这本身就很慢,更不用说发送电子邮件了

CREATE TRIGGER FullfillOrderQCResult
ON Table_1
AFTER INSERT
AS
BEGIN
    SET NOCOUNT ON;

    -----DECLARE VARIABLES-----

    DECLARE @ACTIONPEFORMED varchar(max), @Id int;

    SELECT A.LotCode, A.LineNumber, CONVERT(bit, 0) Done, IDENTITY(int) id -- Use your own id if you have one, just need to uniquely identify each row.
    INTO #FullfillOrderQCResult_temp
    FROM Inserted AS A
    INNER JOIN Table_2 AS B ON A.LotCode = B.DocumentID2
    WHERE B.Result <> 1 and B.[Status] <> 3;

    WHILE EXISTS (SELECT 1 FROM #FullfillOrderQCResult_temp WHERE Done = 0) BEGIN
        SELECT TOP 1 @Id = id, @ACTIONPEFORMED = 
            N'Hello, ' + '<br>' + '<br>'
            + N'The following LOT NUMBER: ' + LotCode + ' has not been approved for this Item: ' + LineNumber
        FROM #FullfillOrderQCResult_temp
        WHERE Done = 0;

        EXEC MSDB.DBO.SP_SEND_DBMAIL
            @PROFILE_NAME = 'SQLMail',
            @RECIPIENTS = 'TEST@gmail.com',
            @SUBJECT = 'LOT NON-Approved',
            @BODY = @ACTIONPEFORMED,
            @IMPORTANCE = 'HIGH',
            @BODY_FORMAT = 'HTML';

        UPDATE #FullfillOrderQCResult_temp SET Done = 1 WHERE id = @Id;
    END;
END;

您犯了经典的101触发器错误,这是假设Inserted(&Deleted)只有一行,而实际上它们可以有0-N,您必须处理它。除此之外,您的问题是什么?您好,@DaleK我很欣赏这些评论和脚本。我还在学习关于触发器的知识,但是我从来没有用JOIN做过一些触发器。我的问题是,为什么在表中输入值时不触发?我知道这是个愚蠢的问题。回答您关于“我的好朋友”的问题是在参数为(Result=1或Status=3)时进行调试。我遵循了您的代码,但在插入测试值时仍存在相同的问题,即未触发电子邮件。我可以看一下您编写的第二个脚本(我还没有创建任何关于队列中事件的内容)。因为您的条件没有得到满足,所以不会触发。您确实需要显示您的精确样本数据。但是根据您显示的内容,表2中的条目的状态为3,这是正常的,如果您添加状态为4,您将发现它发送电子邮件。看这个-你不需要一个触发器来测试你的连接,只需要在真实的表上测试它。你真的应该在你的问题中提供这样的答案。嘿@DaleK,谢谢你分享代码。我对ACTIONPEFORMED有一个问题,但现在我改变了它,它工作了。您好,我学到了一些关于触发器和联接的知识。您犯了经典的101触发器错误,这是假设Inserted(&Deleted)只有一行,而实际上它们可以有0-N,您必须处理它。除此之外,您还有什么问题吗?您好,@DaleK我很感谢您的评论和脚本。我还在学习关于触发器的知识,但是我从来没有用JOIN做过一些触发器。我的问题是,为什么在表中输入值时不触发?我知道这是个愚蠢的问题。回答您关于“我的好朋友”的问题是在参数为(Result=1或Status=3)时进行调试。我遵循了您的代码,但在插入测试值时仍存在相同的问题,即未触发电子邮件。我可以看一下您编写的第二个脚本(我还没有创建任何关于队列中事件的内容)。因为您的条件没有得到满足,所以不会触发。您确实需要显示您的精确样本数据。但是根据您显示的内容,表2中的条目的状态为3,这是正常的,如果您添加状态为4,您将发现它发送电子邮件。看这个-你不需要一个触发器来测试你的连接,只需要在真实的表上测试它。你真的应该在你的问题中提供这样的答案。嘿@DaleK,谢谢你分享代码。我对ACTIONPEFORMED有一个问题,但现在我改变了它,它工作了。你好,我学到了一些关于触发器和连接的知识。
CREATE TRIGGER FullfillOrderQCResult
ON Table_1
AFTER INSERT
AS
BEGIN
    SET NOCOUNT ON;

    -----DECLARE VARIABLES-----

    DECLARE @ACTIONPEFORMED varchar(max), @Id int;

    SELECT A.LotCode, A.LineNumber, CONVERT(bit, 0) Done, IDENTITY(int) id -- Use your own id if you have one, just need to uniquely identify each row.
    INTO #FullfillOrderQCResult_temp
    FROM Inserted AS A
    INNER JOIN Table_2 AS B ON A.LotCode = B.DocumentID2
    WHERE B.Result <> 1 and B.[Status] <> 3;

    WHILE EXISTS (SELECT 1 FROM #FullfillOrderQCResult_temp WHERE Done = 0) BEGIN
        SELECT TOP 1 @Id = id, @ACTIONPEFORMED = 
            N'Hello, ' + '<br>' + '<br>'
            + N'The following LOT NUMBER: ' + LotCode + ' has not been approved for this Item: ' + LineNumber
        FROM #FullfillOrderQCResult_temp
        WHERE Done = 0;

        EXEC MSDB.DBO.SP_SEND_DBMAIL
            @PROFILE_NAME = 'SQLMail',
            @RECIPIENTS = 'TEST@gmail.com',
            @SUBJECT = 'LOT NON-Approved',
            @BODY = @ACTIONPEFORMED,
            @IMPORTANCE = 'HIGH',
            @BODY_FORMAT = 'HTML';

        UPDATE #FullfillOrderQCResult_temp SET Done = 1 WHERE id = @Id;
    END;
END;
CREATE TRIGGER FullfillOrderQCResult
ON Table_1
AFTER INSERT
AS
BEGIN
    SET NOCOUNT ON;

    INSERT INTO MyEventQueue (A.LotCode, A.LineNumber) -- Any other information required to identify the records etc
        SELECT A.LotCode, A.LineNumber
        FROM Inserted AS A
        INNER JOIN Table_2 AS B ON A.LotCode = B.DocumentID2
        WHERE B.Result <> 1 and B.[Status] <> 3;
END;