当插入事件发生时,我可以将列值更新为触发器吗?

Posted

技术标签:

【中文标题】当插入事件发生时,我可以将列值更新为触发器吗?【英文标题】:Can I update column value into a trigger when insert event happens? 【发布时间】:2011-06-29 17:26:15 【问题描述】:

我使用的是 SQL Server 2008。我可以更新发生插入触发器的同一个表中的列值吗?

也就是说,我可以使用此代码吗?

CREATE TRIGGER tr_Table1_Insert_Table1name
ON Table1name
FOR INSERT AS

BEGIN

 UPDATE @NEW
    SET COLUMN = 3;

END
GO

如果“否”,如何做到这一点?

【问题讨论】:

我不明白你想要做什么——或者为什么你不会在列上使用 DEFAULT 约束...... @OMG Ponies:是的,+1。如果所有 OP 想要提供一个默认值,他应该在表定义中这样做。如果他想确保用户不能为插入的记录提供不同的值,那么触发器可能是正确的方法。 【参考方案1】:

如果我正确理解您的问题,这应该可以满足您的要求:

CREATE TABLE dbo.Test_Insert_Trigger (
    my_id INT NOT NULL,
    my_string VARCHAR(20) NULL,
    CONSTRAINT PK_Test_Insert_Trigger PRIMARY KEY CLUSTERED (my_id)
)
GO
CREATE TRIGGER dbo.tri_Test_Insert_Trigger
ON Test_Insert_Trigger FOR INSERT
AS
BEGIN
    UPDATE T
    SET my_string = CAST(I.my_id AS VARCHAR(20))
    FROM
        INSERTED I
    INNER JOIN dbo.Test_Insert_Trigger T ON
        T.my_id = I.my_id
END
GO
INSERT INTO dbo.Test_Insert_Trigger (my_id) VALUES (1)
SELECT * FROM dbo.Test_Insert_Trigger

正如 OMG Ponies 指出的那样,在许多情况下,DEFAULT 约束是您真正想要的。

【讨论】:

你试过了吗?这是对上面脚本的一个非常简单的更改。不过我会给你一个提示:是的。 我的朋友,我可以做这个代码吗? 更新插入集 ID = 3; @Luciano:您不能在触发器中修改inserted 表。 这就是我应该知道的!谢谢。 您无法更新系统INSERTED 表,但您可以更新导致插入触发器触发的表。【参考方案2】:

是的,你可以。您的代码没有问题,因为 UPDATE 语句不会干扰您正在覆盖的 INSERT。你会想要这样的东西:

UPDATE Table
SET Column = 3
WHERE Table.ID IN (SELECT ID FROM inserted)
  AND Table.ID NOT IN (SELECT ID FROM deleted);

这是假设您的表有一个 ID 列。

【讨论】:

事实上,您不需要在 FOR INSERT 触发器中进行第二次测试 (NOT IN deleted)。当然,虽然它不会改变任何东西。【参考方案3】:

您必须在插入触发器后使用更新行。

CREATE TRIGGER tr_Table1_Insert_Table1name ON Table1name 
    AFTER INSERT 
AS  BEGIN   
    UPDATE Table1
    SET COLUMN = 3
    Where ...  
END 
GO

【讨论】:

OP 使用已将其触发器声明为FOR INSERT,这是相同的,因为AFTER INSERT = FOR INSERT in SQL Server。该问题与不正确的更新有关。

以上是关于当插入事件发生时,我可以将列值更新为触发器吗?的主要内容,如果未能解决你的问题,请参考以下文章

PostgreSQL 触发器

JS触发事件集锦

11.PostgreSQL 触发器

SQL Server在复制时触发

使用触发器在新行上设置列

15)触发器