【问题标题】:SQL Server 2005 triggersSQL Server 2005 触发器
【发布时间】:2023-04-07 03:51:02
【问题描述】:

我在表上创建了一个触发器以进行更新。如果发生任何更新,我想将旧值存储在单独的表中。我正在尝试从“插入”表中获取旧值,但更新后该表未填充旧值。

这里是示例代码:

CREATE TRIGGER [dbo].[Logs_Update]
   ON  [dbo].[Logs] AFTER  UPDATE
AS 

 DECLARE @url varchar(50)

BEGIN

 SELECT @url =  i.url 
   FROM INSERTED i

 INSERT INTO dbo.Triggers_tbl
   (ID, URL) 
 VALUES
   (1000, @url)

END

我从插入的表中得到 @url 为 null。

请告诉我触发器出了什么问题

【问题讨论】:

    标签: sql sql-server sql-server-2005 triggers


    【解决方案1】:

    DELETED 表包含“旧”值,“INSERTED”表包含“新”值。

    此外,如果您的更新影响多行,则 INSERTED 和 DELETED 表可能包含多行,因此您可能应该使用 INSERT SELECT 而不是变量来运行插入。

    INSERT INTO dbo.Triggers_tbl(URL) SELECT d.url FROM DELETED d
    

    【讨论】:

      【解决方案2】:

      “旧”值(在 UPDATE 之后)在 Deleted 伪表中可用:

      CREATE TRIGGER [dbo].[Logs_Update]
         ON  [dbo].[Logs]
         AFTER  UPDATE
      AS 
         DECLARE @url varchar(50)
      
         SELECT @url =  d.url from deleted d
      
         INSERT INTO dbo.Triggers_tbl(ID,URL) VALUES(1000,@url)
      

      正如 HLGEM 正确评论的那样,OP 的代码假设触发器将分别为每一行调用 - 这是不正确的。

      因此,触发器代码确实应该处理正在更新的一组行,因此它应该是这样的:

      CREATE TRIGGER [dbo].[Logs_Update]
         ON  [dbo].[Logs]
         AFTER  UPDATE
      AS 
         INSERT INTO dbo.Triggers_tbl(ID,URL) 
            SELECT 1000, d.url
            FROM Deleted d
      

      或类似的东西。

      【讨论】:

      • 对于触发器的编程技术仍然很糟糕,永远不要假设只会插入或删除一条记录。
      • @HLGEM:完全同意-我也没有编写此代码-我只是试图向 OP 说明如何使用“已删除”表而不是“已插入”表-仅此而已
      【解决方案3】:

      更新的记录在 DELETED 虚拟表中,而不是在 INSERTED 中。将“从插入”更改为“从删除”,这应该可以工作。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-05-25
        • 2010-09-14
        • 1970-01-01
        • 2014-10-09
        • 2011-09-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多