sql-server - 使用触发器查明插入、更新或删除了哪些行

标签 sql-server tsql

我在数据库中有一个名为 indication 的表,它包含三列 NameAgeEnable

我想创建一个触发器,每当 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 INSERTAFTER 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 中,每个操作触发一次,而不是每触发一次。这意味着在触发器执行期间,InsertedDeleted 元表中的行数与受操作影响的行数一样多。请小心,不要编写假设只有一行的触发器。

关于sql-server - 使用触发器查明插入、更新或删除了哪些行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25279318/

相关文章:

OS X EL Capitan 上的 MySQL 5.7.13 Homebrew : ERROR! 服务器在启动时退出而不更新 PID 文件

sql-server - 尝试通过 knex 连接到 Mssql 服务器

sql - SELECT SQL 变量 - 我应该避免使用这种语法并始终使用 SET 吗?

sql - 从 SQL 获取未转义的 JSON

sql-server - SQL Server,T-SQL 是否有更快的方法来对我的问题中的以下字符串进行子字符串化?

sql-server - 像 '%[a-z]%' collat​​e SQL_Latin1_General_CP1_CS_AS 仍然返回大写?

sql - 按列分组不存在

sql - sql server中的3d空间对象

sql - 添加非空列从其他列取值

sql - T-SQL - 在单个表中查找 PK 的差异(自联接?)