使用 JOIN 表触发后
After Trigger with JOIN Tables
任务:创建一个 AFTER TRIGGER 以完成 JOIN 的条件。创建某些记录时,触发器将位于 table_1 中。同时,table_2 有一个公共列,其中包含条件需要具有的一些参数。
每次 table_2 中的结果 <> 1 AND 状态 <> 3 和 ALERT 应该被发送
-- 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
CREATE TRIGGER FullfillOrderQCResult
ON Table_1
AFTER INSERT
AS
BEGIN
-----DECLARE VARIABLES-----
DECLARE @LOTNUMBER VARCHAR(50)
DECLARE @ACTIONPEFORMED VARCHAR(MAX)
DECLARE @ITEM INT
DECLARE @RESULT TINYINT
DECLARE @STATUS TINYINT
SELECT @LOTNUMBER = A.LotCode, @ITEM = A.LineNumber, @RESULT = B.Result, @STATUS = B.Status
FROM inserted AS A
JOIN Table_2 AS B
ON A.LotCode = B.DocumentID2
-----CONDITION WHEN I INSERT A VALUE-----
IF (@RESULT <> 1 AND @STATUS <> 3)
BEGIN
SET @ACTIONPEFORMED =
N'Hello, ' + '<br>' + '<br>'
+ N' The following LOT NUMBER: ' + @LOTNUMBER + ' has not been approved for this Item: '
EXEC MSDB.DBO.SP_SEND_DBMAIL
@PROFILE_NAME = 'SQLMail',
@RECIPIENTS = 'TEST@gmail.com',
@SUBJECT = 'LOT NON-Approved',
@BODY = @ACTIONPEFORMED,
@IMPORTANCE = 'HIGH',
@BODY_FORMAT = 'HTML'
END
ELSE
PRINT 'ALL GOOD MY FRIEND'
END
TESTING THE TRIGGER
--------INSERT VALUES------------------
INSERT INTO Table_1 (LotCode,LineNumber)
values ('00000','xxxx')
-----EXISTING VALUES-----
INSERT INTO Table_2 (CreationUser,DocumentID1,DocumentID2,DocumentID3,Result,Status)
values ('JL','00000','00000','00000',2,3)
下面向您展示了如何处理 Inserted
可能有多行的情况。对于触发器来说,这确实不是理想的行为,因为您必须处理结果 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;
我不知道您是否仍需要 'ALL GOOD MY FRIEND'
的概念,因为您可能 none 的某些或所有行都有问题。无论如何,我假设 print
仅用于调试。
也就是说,将事件推入队列并让服务进程处理事件会更好,因为触发器确实应该尽可能快。并且可以以基于集合的方式处理向队列添加事件,例如
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;
任务:创建一个 AFTER TRIGGER 以完成 JOIN 的条件。创建某些记录时,触发器将位于 table_1 中。同时,table_2 有一个公共列,其中包含条件需要具有的一些参数。
每次 table_2 中的结果 <> 1 AND 状态 <> 3 和 ALERT 应该被发送
-- 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
CREATE TRIGGER FullfillOrderQCResult
ON Table_1
AFTER INSERT
AS
BEGIN
-----DECLARE VARIABLES-----
DECLARE @LOTNUMBER VARCHAR(50)
DECLARE @ACTIONPEFORMED VARCHAR(MAX)
DECLARE @ITEM INT
DECLARE @RESULT TINYINT
DECLARE @STATUS TINYINT
SELECT @LOTNUMBER = A.LotCode, @ITEM = A.LineNumber, @RESULT = B.Result, @STATUS = B.Status
FROM inserted AS A
JOIN Table_2 AS B
ON A.LotCode = B.DocumentID2
-----CONDITION WHEN I INSERT A VALUE-----
IF (@RESULT <> 1 AND @STATUS <> 3)
BEGIN
SET @ACTIONPEFORMED =
N'Hello, ' + '<br>' + '<br>'
+ N' The following LOT NUMBER: ' + @LOTNUMBER + ' has not been approved for this Item: '
EXEC MSDB.DBO.SP_SEND_DBMAIL
@PROFILE_NAME = 'SQLMail',
@RECIPIENTS = 'TEST@gmail.com',
@SUBJECT = 'LOT NON-Approved',
@BODY = @ACTIONPEFORMED,
@IMPORTANCE = 'HIGH',
@BODY_FORMAT = 'HTML'
END
ELSE
PRINT 'ALL GOOD MY FRIEND'
END
TESTING THE TRIGGER
--------INSERT VALUES------------------
INSERT INTO Table_1 (LotCode,LineNumber)
values ('00000','xxxx')
-----EXISTING VALUES-----
INSERT INTO Table_2 (CreationUser,DocumentID1,DocumentID2,DocumentID3,Result,Status)
values ('JL','00000','00000','00000',2,3)
下面向您展示了如何处理 Inserted
可能有多行的情况。对于触发器来说,这确实不是理想的行为,因为您必须处理结果 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;
我不知道您是否仍需要 'ALL GOOD MY FRIEND'
的概念,因为您可能 none 的某些或所有行都有问题。无论如何,我假设 print
仅用于调试。
也就是说,将事件推入队列并让服务进程处理事件会更好,因为触发器确实应该尽可能快。并且可以以基于集合的方式处理向队列添加事件,例如
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;