【问题标题】:Why my after update trigger is executing on insert although I have separate trigger for insert as well为什么我的更新后触发器在插入时执行,尽管我也有单独的插入触发器
【发布时间】:2021-11-15 14:03:33
【问题描述】:
/* trigger for update */
create trigger add_date
on students 
after update
as
    update students 
    set dtModify = getdate()
    where id = (select id from inserted)

/* trigger for insert */
create trigger add_date_insert 
on students 
after insert
as 
    update students 
    set dtEnter = getdate() 
    where id = (select id from inserted)

【问题讨论】:

  • 好吧 - 你的 AFTER INSERT 触发器会更新表 - 这样就会触发 AFTER UPDATE 触发器。 ....
  • 您需要阅读触发器...Inserted 是一个包含行的表,可能包含多行(或无行),您需要处理它。
  • 您能否为此提出一个可能的解决方案。如何限制插入时的更新触发器。谢谢
  • 我知道这是一个练习,但请注意,在现实世界中,将修改信息内联存储在表格中通常是不够的 - 每次更新都会删除任何以前的信息。
  • 请澄清您的具体问题或提供其他详细信息以准确突出您的需求。正如目前所写的那样,很难准确地说出你在问什么。

标签: sql sql-server tsql triggers


【解决方案1】:

首先 - 对于 INSERT - 我会使用带有 默认约束DATETIME2(3) 列 - 然后你不需要触发器:

CREATE TABLE dbo.Students
(
    // your columns here
    dtEnter DATETIME2(3)
        CONSTRAINT DF_Students_dtEnter DEFAULT (SYSDATETIME())
)

现在,每次插入一行时在要插入值的列列表中指定 dtEnter 列 - SQL Server 会自动设置它:

INSERT INTO dbo.Students (list-of-columns-WITHOUT-dtEnter)
VALUES (list-of-values)

对于更新,您需要使用触发器 - 不能为此使用默认约束。使用此触发器 - 确保处理 Inserted 可能包含多行的事实!

CREATE TRIGGER add_date
ON dbo.Students 
AFTER UPDATE
AS
    UPDATE dbo.students 
    SET dtModify = SYSDATETIME()
    WHERE id IN (SELECT id FROM inserted)

【讨论】:

【解决方案2】:

如果您对inserted 感到困惑,则无需担心。此表具有触发触发的插入行。

现在SQL Server中只有inserteddeleted两个这样的表

  • 在插入的情况下,inserted 已插入行。
  • 在删除的情况下,deleted 有被删除的行。
  • 在更新的情况下,有问题的行首先被删除并因此放置在deleted 中,然后插入带有更新数据的新行,您可以在表inserted 中找到这些数据。因此,当更新实际上是两个操作删除和插入的组合时,您可能会将更新视为单个操作。

如果您希望触发器仅在更新的情况下运行逻辑,您可以像这样进行 IF 检查:

If exists (Select * from inserted) and exists(Select * from deleted)

并像这样将您的触发逻辑放在这个块中

If exists (Select * from inserted) and exists(Select * from deleted)
BEGIN
--Update Logic
END
If exists (Select * from inserted) and not exists(Select * from deleted)
BEGIN
--Inser Logic
END

【讨论】:

  • 行”- 不,不,不,不,不。这是初学者在 SQL Server 中使用触发器时最常犯的一个错误。这些表可以包含 0、1 或 多个 行。如果您将它们视为只包含一行,那么您只是编写了一个损坏的触发器。
  • 这个触发器是怎么坏的。我只是检查以区分插入和更新。这些表中的行数如何使触发器损坏?
  • 仅仅因为我是用最简单的场景来解释,以便于理解,就让整个解释崩溃了?
猜你喜欢
  • 2021-03-08
  • 2016-10-13
  • 1970-01-01
  • 1970-01-01
  • 2012-06-06
  • 2015-11-06
  • 1970-01-01
  • 2017-06-26
  • 2021-10-13
相关资源
最近更新 更多