AFTER DELETE 触发器触发但不将记录插入审计表

Posted

技术标签:

【中文标题】AFTER DELETE 触发器触发但不将记录插入审计表【英文标题】:AFTER DELETE Trigger fires off but does not Insert a record into an Audit table 【发布时间】:2018-11-06 22:30:06 【问题描述】:

我使用的是 SQL Server 2016。下面是适用于 UPDATE 和 INSERT 操作的代码。这意味着在将记录插入或更新到 MyDB.[dbo].[DocumentText] 表后,相应的记录将插入到 [AnotherDB].[dbo].[Audit]

但相同的场景不适用于同一张表上的 DELETE 操作。 但是当我从 MyDB.[dbo].[DocumentText] 表中删除记录时,我确实看到触发器正在触发。删除单个记录时,DELETE 操作的结果如下所示:

(0 行受影响) (受影响的 1 行)

同时,UPDATE 和 INSERT 操作的结果如下所示(考虑单个记录):

(1 行受影响) (受影响的 1 行)

除此之外,此表上没有定义其他触发器...

CREATE TRIGGER [dbo].[TR_DocumentText_UPDATE_INSERT_DELETE]
   ON MyDB.[dbo].[DocumentText] AFTER INSERT, DELETE, UPDATE
   NOT FOR REPLICATION 
AS 
BEGIN
            ;WITH CTE AS (
            SELECT ISNULL(ins.DocumentID, del.DocumentID) AS DocumentID,
                CASE 
                    WHEN ins.DocumentID IS NOT NULL AND ins.DocumentID  = del.DocumentID THEN 'UPDATE' 
                    WHEN ins.DocumentID IS NOT NULL AND del.DocumentID IS NULL THEN 'INSERT'
                    ELSE 'DELETE' END AS AuditType         
                FROM inserted ins 
                FULL OUTER JOIN deleted del 
                        ON ins.DocumentID = del.DocumentID
                        )

            ,AUDIT_CTE AS (
            SELECT          
                CTE.DocumentID AS PkId, 
                'ODRT' AS Code,
                CTE.AuditType,
                'TSRE' AS MainEntityCode,
                doc.OppId AS MainEntityPkId
            FROM [MyDB].[dbo].[DocumentText] t WITH (NOLOCK)
            INNER JOIN [MyDB].[dbo].[Document] doc WITH (NOLOCK)
                        ON t.DocumentID = doc.DocumentID
            INNER JOIN CTE 
                        ON CTE.DocumentID = t.DocumentID
                            WHERE doc.OppId IS NOT NULL
                        )

            INSERT [AnotherDB].[dbo].[Audit] (Code, PKID, AuditType, MainEntityCode, MainEntityPKID)
            SELECT
                Code,
                PKID, 
                AuditType,
                MainEntityCode,
                MainEntityPkId
            FROM AUDIT_CTE;

END

【问题讨论】:

呃,在 audit_cte 中,您在第一个 CTE(在删除语句的情况下会获取已删除的 documentID)和原始表(删除记录的位置)之间使用内部连接)。这不会产生任何结果(如预期的那样)。我认为你想要做的是从 audit_cte 中删除 FROM [MyDB].[dbo].[DocumentText] t WITH (NOLOCK) 并加入 [MyDB].[dbo].[Document]CTE... 感谢 ZLK,您的建议尽可能简单。它解决了 DELETE 操作的问题。非常感谢。您可以将此作为答案发布,因此我可以接受。 【参考方案1】:

按照 ZLK 的建议,我应该只删除 FROM [MyDB].[dbo].[DocumentText] t WITH (NOLOCK) 并直接查询为“FROM CTE ...”。就是这样。

【讨论】:

以上是关于AFTER DELETE 触发器触发但不将记录插入审计表的主要内容,如果未能解决你的问题,请参考以下文章

触发器

使用AFTER INSERT触发器将实体框架插入表中

sql server 的after触发器之insert触发器实例

SQL 触发器

MySQL触发器初试:当A表插入新记录,自动在B表中插入相同ID的记录

MYSQL---触发器简单了解