我在数据库中有一个名为 indication 的表,它包含三列 Name
、Age
和 Enable
。
我想创建一个触发器,每当 Age
小于 18 且 Enable
为真时,它就会在我的警报表中插入一个警报,我想检查指示表在它被插入的确切时刻,这样我就可以检查它是否应该在警报中插入。
我在 MSDN 上找到了 COLUMNS_UPDATED (Transact-SQL)
,它适用于更新的列,ROWS_UPDATED
是否有相同的东西?
最佳答案
您始终可以将触发器设置为仅响应INSERT
操作,使用
CREATE TRIGGER TR_Whatever_I ON dbo.YourTable FOR INSERT
AS
... (body of trigger)
请注意 FOR INSERT
与 AFTER INSERT
相同。您还可以选择 INSTEAD OF
,但您必须自己执行数据修改。 SQL Server 中没有BEFORE
触发器。
在某些情况下,一次处理多个 Action 非常方便,因为不同 Action 的脚本是相似的——既然可以只写一个触发器,为什么还要写三个呢?因此,如果您的触发器看起来更像这样:
CREATE TRIGGER TR_Whatever_IUD ON dbo.YourTable FOR INSERT, UPDATE, DELETE
AS
... (body of trigger)
那么您不会自动知道它是体内的插入物。在这种情况下,您可以检测它是否是类似这样的插入:
IF EXISTS (SELECT * FROM Inserted)
AND NOT EXISTS (SELECT * FROM Deleted) BEGIN
--It's an INSERT.
END
或者,如果您想确定它是三个 DML 操作中的哪一个:
DECLARE @DataOperation char(1);
SET @DataOperation =
CASE
WHEN NOT EXISTS (SELECT * FROM Inserted) THEN 'D'
WHEN NOT EXISTS (SELECT * FROM Deleted) THEN 'I'
ELSE 'U'
END
;
如果 DML 操作不影响任何行(例如,UPDATE dbo.YourTable SET Column = '' WHERE 1 = 0
),触发器仍会运行。在这种情况下,您无法判断它是更新、删除还是插入——但由于没有发生修改,所以这无关紧要。
特别说明
值得一提的是,在 SQL Server 中,每个操作触发一次,而不是每行触发一次。这意味着在触发器执行期间,Inserted
和 Deleted
元表中的行数与受操作影响的行数一样多。请小心,不要编写假设只有一行的触发器。
关于sql-server - 使用触发器查明插入、更新或删除了哪些行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25279318/