Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/73.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在插入后触发AFTER UPDATE触发器-sql server_Sql_Sql Server_Datatrigger - Fatal编程技术网

在插入后触发AFTER UPDATE触发器-sql server

在插入后触发AFTER UPDATE触发器-sql server,sql,sql-server,datatrigger,Sql,Sql Server,Datatrigger,我有两个数据触发器,一个应该在更新后触发,另一个应该在插入后触发。更新触发器的开头是这样的: USE [Database] GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO ALTER TRIGGER [dbo].[UpdateTrigger] ON [dbo].[Table1] AFTER UPDATE AS BEGIN (...) after i

我有两个数据触发器,一个应该在更新后触发,另一个应该在插入后触发。更新触发器的开头是这样的:

    USE [Database]
    GO
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    ALTER TRIGGER [dbo].[UpdateTrigger]
    ON [dbo].[Table1]
    AFTER UPDATE
    AS
   BEGIN
   (...)

after insert触发器看起来完全相同,只是存在after insert而不是after UPDATE。当我更新Table1时,只触发update触发器。但是,当我插入时,两个触发器都被触发。为什么?我怎样才能解决它

触发触发器时,有两个虚拟表:删除和插入。插入记录时,记录仅在插入的表中,而更新记录时,删除的表中有旧记录,插入的表中有新记录。所以,基本上,当您进行更新时,您正在进行删除和插入。通过确定删除的表中是否有记录,可以很容易地解决这个问题。如果有,则它是更新,如果没有,则它是插入。

我与JerryBox有相同的经历,当插入触发器触发时,单独的更新触发器将触发

我想要的是在插入新记录时,插入触发器将在创建记录时插入日期时间戳,并插入创建记录的用户名。相反,如果记录已更新,则添加/更新上次修改的日期时间和上次修改的用户名

在我的例子中,当一条新记录插入到表中时,insert触发器将触发并向同一表中的字段(即CreatedBy和CreatedDateTime字段)添加值。更新触发器“看到”这些添加内容是对现有记录的更新,因此还将插入ModifiedBy和ModifiedDateTime字段

换句话说,插入一条新记录将导致insert和update触发器同时触发

在阅读德米特里吉·库尔塔塞夫对帖子的评论后,我提出了以下解决方案:

将INSERT和UPDATE触发器组合成一个触发器xxx 在插入后的xxx上,更新。。。 检查已删除表中的旧记录 如果删除的表中存在记录,则执行更新操作 如果删除的表中不存在任何记录,则执行插入操作 表演 将两个触发器组合到一个触发器中的结果是,由后插入触发器更新记录不会触发后更新触发器

USE [Database]
GO

CREATE TABLE [dbo].[Table1](
    [id] [int] IDENTITY(1,1) PRIMARY KEY,
    [Data] [nvarchar](255) NULL,
    [CreatedBy] [nvarchar](255) NULL,
    [CreatedDateTime] [datetime] NULL,
    [ModifiedBy] [nvarchar](255) NULL,
    [ModifiedDateTime] [datetime] NULL)
GO

CREATE TRIGGER [dbo].[UpdateTrigger]
ON [dbo].[Table1]
AFTER INSERT, UPDATE
AS
BEGIN
IF EXISTS (SELECT 1 FROM deleted)
       UPDATE [dbo].[Table1]
       SET [ModifiedBy] = SYSTEM_USER, 
       [ModifiedDateTime] = SYSDATETIME()
       FROM inserted i 
       WHERE i.id = [dbo].[Table1].id
   ELSE
       UPDATE [dbo].[Table1]
       SET [CreatedBy] = SYSTEM_USER,
           [CreatedDateTime] = SYSDATETIME()
       FROM inserted i 
       WHERE i.id = [dbo].[Table1].id
   END
GO

编辑:格式化,改进解释以响应andronicus的反馈

如果没有看到两个触发器中的代码,我们无法确定这里发生了什么。您所描述的是不可能的。如果触发器定义为“更新后”,则在插入后不会触发。您可以共享触发器中的代码吗?如果我们*假设您的insert触发器更新同一个表,那么该操作将导致执行update触发器。我还猜您的观察是基于更新触发器的效果,而没有实际调试代码以查看插入的触发器的效果。更新触发器可能会覆盖插入触发器的效果?我已尝试使用以下命令检查删除中是否有任何记录:if EXISTSSELECT*FROM DELETED,但条件返回true,尽管它是插入。我是否使用了错误的语法?我不确定语法中是否存在问题,但如果您说插入后删除了表中的记录,那么肯定有问题,您可以为插入和更新创建一个触发器。在插入、更新…之后,在xxx上创建触发器xxx。如上所述,您可以将两个触发器合并为一个触发器。如果您对更新有不同的逻辑,并且如果您知道将要更新的确切列,则可以使用If update column。如果我创建1个触发器而不是3个触发器,这有什么区别?我仍然需要确定它是更新还是插入,以便为每个操作执行特定的代码。