代码之家  ›  专栏  ›  技术社区  ›  bedrock

为什么INSERT的SQL数据库触发器实际上会更新未指定的字段?

  •  0
  • bedrock  · 技术社区  · 4 年前

    SQL Server数据库表有以下4列:

    CreatedBy
    UpdatedBy
    CreateDatetime
    UpdateDatetime
    

    我创建了一个用于更新的触发器 CreatedBy & CreateDatetime 列后 INSERT .

    以下是该触发器的代码:

    SET ANSI_NULLS ON
    GO
    
    SET QUOTED_IDENTIFIER ON
    GO
    
    CREATE TRIGGER [dbo].[TestDb_create_time]
    ON [dbo].[trgn]
    AFTER INSERT
    AS 
    BEGIN
        SET NOCOUNT ON;
    
        UPDATE TestDb 
        SET CreateDatetime = GETDATE(), CreatedBy = USER_NAME()
        FROM inserted
        WHERE inserted.TestDbID = TestDb.TestDbID
    END
    

    当触发器在insert之后运行时,除了更新 CreatedBy & CreateDatetime 专栏,它也更新了 UpdatedBy UpdateDatetime .触发器中不包括最后两列。

    为什么触发器也会更新它们?如何防止触发器更新未指定的列?

    为这个问题添加更多细节:

    SQL Server表:

    SET ANSI_NULLS ON
    GO
    
    SET QUOTED_IDENTIFIER ON
    GO
    
    CREATE TABLE [dbo].[TestDb]
    (
        [TestDbID] [int] IDENTITY(1,1) NOT NULL,
        [Item1] [varchar](30) NULL,
        [Item2] [varchar](30) NULL,
        [CreatedBy] [varchar](30) NULL,
        [UpdatedBy] [varchar](30) NULL,
        [CreateDatetime] [datetime] NULL,
        [UpdateDatetime] [datetime] NULL,
    
        CONSTRAINT [PK_TestDb] 
            PRIMARY KEY CLUSTERED ([TestDbID] ASC)
                    WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, 
                          IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, 
                          ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
    ) ON [PRIMARY]
    

    的SQL Server触发器 插入 :

    SET ANSI_NULLS ON
    GO
    
    SET QUOTED_IDENTIFIER ON
    GO
    
    CREATE TRIGGER [dbo].[TestDb_create_time]
    ON [dbo].[TestDb]
    AFTER INSERT
    AS 
    BEGIN
        SET NOCOUNT ON;
    
        UPDATE TestDb 
        SET CreateDatetime = GETDATE(), CreatedBy = USER_NAME()
        FROM inserted
        WHERE inserted.TestDbID = TestDb.TestDbID
    END
    
    ALTER TABLE [dbo].[TestDb] ENABLE TRIGGER [TestDb_create_time]
    

    为了测试触发器,我使用两个不同的用户帐户执行了两条SQL语句:

    INSERT INTO TestDb (item1) 
    VALUES ('new record1')    --- connected with Windows account
    
    INSERT INTO TestDb (item1) 
    VALUES ('record2') --- connected with SQL user account
    

    在插入之后 TestDb 表明 更新时间 列在2条新插入的记录中有值。这个 更新时间 触发器中不包括列。

    为什么触发器会更新那个专栏?

    Data in test DB table:

    0 回复  |  直到 4 年前