触发以检测列值的变化

Trigger to detect changes in column value

我想创建一个触发器,在更改 table Y[=26= 中的 X 列中的记录内容后调用该触发器] 并显示 table Y 中有多少条记录,其中先前的内容在列 X.

例如,

  1. 将记录字段“颜色”从“蓝色”更改为“绿色”,
  2. 显示当前有多少条“颜色”字段设置为“蓝色”的记录。

这是我已经尝试过的方法:

USE [DTBS]
GO

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER TRIGGER [dbo].[dbo.how_many]
   ON [dbo].[Person]
   FOR INSERT, UPDATE
AS BEGIN
    SET NOCOUNT ON;
    IF UPDATE (color)
        BEGIN

        DECLARE @color VARCHAR(32);
        DECLARE @count INT;

        SELECT @color = color FROM deleted;

        SELECT @count = COUNT(id)
        FROM Person
        WHERE Person.color = @color

        PRINT (@count)
    END
END

我正在开发 SQL Server Management Studio 2019,目前当我尝试调用触发器时没有任何反应。

  1. 您需要阅读有关 Inserted & Deleted Pseudo Tables 的内容,因为它们可以有 0-N 行并且您的触发器需要处理它。使用基于集合的方法解决了这个问题。

  2. 这导致您可能需要同时更新多种颜色。

  3. 如果您正在检测更改并想要访问旧值,则不需要 INSERT 触发器。

  4. 触发器不是为 return 数据设计的。我已经向您展示了如何捕获您想要的信息,但最终您需要一种不同的机制来使用它,例如插入不同的 table.

ALTER TRIGGER [dbo].[dbo.how_many]
    ON [dbo].[Person]
    FOR UPDATE
AS BEGIN
    SET NOCOUNT ON;
   
    IF UPDATE (color) BEGIN

        -- This gives *all* the old colours prior to update
        SELECT D.Color
        FROM Inserted I
        INNER JOIN Deleted D ON D.id = I.id -- One assumes you have an id column
        -- Assuming Color is never null
        WHERE D.Color != I.Color
        GROUP BY D.Color;

        -- If you then want a count you would do
        SELECT COUNT(id), Color
        FROM Person
        WHERE Person.Color IN (
            -- Repeat query from above
            SELECT D.Color
            FROM Inserted I
            INNER JOIN Deleted D ON D.id = I.id
            WHERE D.Color != I.Color
            GROUP BY D.Color
        )
        GROUP BY Color;

    END;
END;