Sql 后触发器与联接表
任务:创建一个AFTER触发器来完成一个连接条件。当创建一些记录时,触发器将位于表_1中。同时,表2有一个公共列,其中有一些条件需要的参数 每次应发送表2中的结果1和状态3以及警报时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
-- 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;