为什么 FOR/AFTER DELETE 触发器中删除的 table 不包含已删除记录的数据?

Why doesn't the deleted table in a FOR/AFTER DELETE Trigger contain data of the Deleted Record?

鉴于以下审核table:

CREATE TABLE Auditing.[Record Deletion Times]
(
    ID BIGINT IDENTITY NOT NULL,
    [Schema] NVARCHAR(128) NOT NULL,
    [Table] NVARCHAR(256) NOT NULL,
    [Record ID] INT NOT NULL,
    [Date-Time] DATETIME2 NOT NULL,
    [Record Information] NVARCHAR(1024) NULL,
    CONSTRAINT [Record Deleted Times Primary Key] PRIMARY KEY CLUSTERED
    (
        ID ASC
    ),
    CONSTRAINT [Record Deleted Modified Times Unique Key] UNIQUE NONCLUSTERED
    (
        [Schema] ASC,
        [Table] ASC,
        [Record ID] ASC,
        [Date-Time] ASC
    )
)

和以下数据table:

CREATE TABLE [dbo].[Items]
(
    [ID] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY,
    [Key] [varchar](50) NOT NULL,
    [Value] [varchar](255) NOT NULL
)

我想要一个触发器,当它从 Items 中删除时,它将记录信息到 Record Deletion Times。我发现我可以使用 INSTEAD OF 触发器来做到这一点(我记录数据然后手动删除触发器中的记录)但想知道为什么 FORAFTER 触发器不需要我自己执行删除就不会做同样的事情。我的猜测是 deleted 不包含有关删除记录后删除的任何数据(调试触发器的最佳方法是什么?)。

这是我希望使用的触发器,它未能在 Record Deletion Times 中记录任何内容:

CREATE TRIGGER [Items Deleted]
    ON Items
FOR DELETE
AS
    INSERT INTO Auditing.[Record Deletion Times]
    SELECT
        'dbo',
        'Items',
        deleted.ID,
        GETUTCDATE(),
        CONCAT
        (
            'Key: ''',
            Items.Key,
            ''' Value: ''',
            Items.Value,
            ''''
        )
    FROM Items
    JOIN deleted ON deleted.ID = Items.ID

这是我最终使用的触发器:

CREATE TRIGGER [Items Deleted]
    ON Items
INSTEAD OF DELETE
AS
BEGIN
    INSERT INTO Auditing.[Record Deletion Times]
    SELECT
        'dbo',
        'Items',
        deleted.ID,
        GETUTCDATE(),
        CONCAT
        (
            'Key: ''',
            Items.Key,
            ''' Value: ''',
            Items.Value,
            ''''
        )
    FROM Items
    JOIN deleted ON deleted.ID = Items.ID

    DELETE Items
    FROM Items
    JOIN deleted ON deleted.ID = Items.ID
END

你不应该 selecting 来自 你的 Items table 因为你想要的行现在已被删除。

刚刚 select 来自 Deleted

INSERT INTO RecordDeletionTimes
    SELECT
        'dbo',
        'Items',
        ID,
        GETUTCDATE(),
        CONCAT
        (
            'Key: ''',
            [Key],
            ''' Value: ''',
            Value,
            ''''
        )
    FROM deleted ;

Demo Fiddle

调试触发器的最佳方法是 select * from deleted 并使用 begin tran/rollback.

在 SSMS 中进行测试