触发器的打印语句显示在受实际查询影响的行之前

trigger's print statements show before rows affected by actual query

我对触发器没有太多经验,但我最近开始尝试使用它们。我创建了一个看起来像这样的触发器。我在 Azure Data Studio 中工作,我惊讶地发现我的打印语句和受影响的行数似乎出现在实际 insert/update 受影响的行的消息之前。谁能解释为什么会这样?由于它是一个“AFTER”触发器,我希望首先看到针对初始 insert/update 更新的 # 行语句,然后是我的触发器的打印语句。

create TRIGGER [dbo].[trig_trimField] ON [dbo].[mytable]
AFTER INSERT, UPDATE
AS
print '[dbo].[trig_trimField]'
IF UPDATE (myField)
BEGIN
    declare @issueCount int
    Select @issueCount = count(*) 
    from inserted
    where len(myField+'x')-1 <> len(rtrim(ltrim(myField)))
    print 'myField(s) to fix: '+cast(@issueCount as varchar)

    IF @issueCount > 0
    BEGIN
        UPDATE [dbo].[mytable]
        SET myField = rtrim(ltrim(myField))
        WHERE ID IN (
            SELECT ID
            FROM inserted
            WHERE len(myField+'x')-1 <> len(rtrim(ltrim(myField)))
            )
    END
END
GO

测试代码

insert into [dbo].[mytable] ([myField])
SELECT case
            when ID = 1 then [myField] +' '
            when ID = 2 then ' '+myField
            else myField
            end 
  FROM [dbo].[mytable]
WHERE ID in (1,2,3)

输出

[dbo].[trig_trimField]
myField(s) to fix: 2
(2 rows affected)
(3 rows affected)

触发发生在对目标 table 进行更改之后,但在同一事务中,并且在 DML 成功或失败报告给客户端之前。

触发器可以通过 throw、raiserror 或 rollback 来撤消更改,在这种情况下,客户端不应看到包含行数的 DONE/DONEINPROC 消息,而应该只收到一条错误消息。