触发以检测列值的变化
Trigger to detect changes in column value
我想创建一个触发器,在更改 table Y[=26= 中的 X 列中的记录内容后调用该触发器] 并显示 table Y 中有多少条记录,其中先前的内容在列 X.
例如,
- 将记录字段“颜色”从“蓝色”更改为“绿色”,
- 显示当前有多少条“颜色”字段设置为“蓝色”的记录。
这是我已经尝试过的方法:
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,目前当我尝试调用触发器时没有任何反应。
您需要阅读有关 Inserted & Deleted Pseudo Tables 的内容,因为它们可以有 0-N 行并且您的触发器需要处理它。使用基于集合的方法解决了这个问题。
这导致您可能需要同时更新多种颜色。
如果您正在检测更改并想要访问旧值,则不需要 INSERT
触发器。
触发器不是为 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;
我想创建一个触发器,在更改 table Y[=26= 中的 X 列中的记录内容后调用该触发器] 并显示 table Y 中有多少条记录,其中先前的内容在列 X.
例如,
- 将记录字段“颜色”从“蓝色”更改为“绿色”,
- 显示当前有多少条“颜色”字段设置为“蓝色”的记录。
这是我已经尝试过的方法:
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,目前当我尝试调用触发器时没有任何反应。
您需要阅读有关 Inserted & Deleted Pseudo Tables 的内容,因为它们可以有 0-N 行并且您的触发器需要处理它。使用基于集合的方法解决了这个问题。
这导致您可能需要同时更新多种颜色。
如果您正在检测更改并想要访问旧值,则不需要
INSERT
触发器。触发器不是为 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;