【问题标题】:Trigger that updates just the inserted row仅更新插入行的触发器
【发布时间】:2016-09-08 00:26:40
【问题描述】:

我正在尝试使用 TSQL(或 SQL Server 2008)创建一个简单的触发器。问题是:我当前的触发器正在更新整个表。这在一段时间内很好,但现在表有超过 20k 行。所以我想要一个只更新正在插入的行的触发器。

这是我目前的简单触发器:

CREATE TRIGGER trig_MyPplUpdate
ON [Persons]
FOR INSERT
AS
Begin
 Update Persons
    set MyFile = NULL
    where Len(MyFile) < 60
End

我想我必须使用“插入”表或按主键排序的row_number 函数。有什么想法吗?

【问题讨论】:

    标签: sql-server sql-server-2008 tsql


    【解决方案1】:

    如果有必要在这里使用触发器,我会使用INSTEAD OF 触发器来调整预先插入的值,避免需要将JOIN 重新放到基表中并在之后更新它们。

    CREATE TRIGGER trig_MyPplUpdate
    ON [Persons]
    INSTEAD OF INSERT
    AS
      BEGIN
          INSERT INTO Persons
          SELECT foo,
                 bar,
                 CASE
                   WHEN Len(MyFile) >= 60 THEN MyFile
                 END
          FROM   Inserted
      END  
    

    【讨论】:

    • 好的,让我直截了当地说:“代替”触发器意味着在任何插入发生之前,我的触发器会触发吗?老实说,我不明白您写的内容(从插入中选择?然后是 MyFile?),我将不得不在互联网上对此进行更多研究,但我认为这就是我想要的 =-)。如果你想让我的生活更轻松,你可以多解释一点,但你写的是我需要的起点。非常感谢!
    • @Gaspa79 - 是的。 SQL Server 将使用您的插入语句并构造inserted 伪表,其中包含来自[Persons] 的所有可插入列。然后您从中选择以实际插入到基表中。你没有提供你的表结构,所以我不得不弥补其他列名。
    • 好的,太好了!我现在正在尝试。我假设 When Len(MyFile) >= THEN Myfile 是因为如果不满足该条件,它将不会插入列值,因此它将为空。在另一种情况下,当它满意时,它将插入列(MyFile)。非常感谢,认真的 =-)。
    • @Gaspa79 - 是的,如果不满足条件,则有默认的ELSE NULL
    • 我建议在您的 INSERT 语句中明确指定列名 - 这样,如果您的表突然获得额外的列,您将不会得到任何令人讨厌的惊喜...
    【解决方案2】:

    您需要在UPDATE 语句中加入Inserted 伪表。请始终注意,SQL Server 每个语句触发一次,并且该语句可以很好地一次修改/插入多行 - 因此您的Inserted 表很可能包含不止一行 - 只需在编写触发器时牢记这一点。

    试试这样的:

    CREATE TRIGGER trig_MyPplUpdate
    ON [Persons]
    FOR INSERT
    AS
        UPDATE dbo.Persons
        SET MyFile = NULL
        WHERE Len(MyFile) < 60
        AND PersonID IN (SELECT DISTINCT PersonID FROM Inserted)
    

    或使用任何唯一列(您的主键)来准确获取已插入的那些行。

    【讨论】:

    • 非常感谢您的帮助,我会尝试的!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-08
    • 1970-01-01
    • 1970-01-01
    • 2017-06-26
    • 1970-01-01
    相关资源
    最近更新 更多