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 触发器触发但不将记录插入审计表的主要内容,如果未能解决你的问题,请参考以下文章
sql server 的after触发器之insert触发器实例