【问题标题】:Handle multiple rows in sql trigger update在sql触发器更新中处理多行
【发布时间】:2013-12-11 15:23:58
【问题描述】:

如何将多行处理为更新触发器/如何修改我的实际触发器以具有当前行为?如果我只更新一行效果很好,但如果我同时更新多行我会收到错误:

消息 512,级别 16,状态 1,过程 TriggerUpdateAdvert,第 9 行
子查询返回超过 1 个值。当子查询跟随 =、!=、、>= 或子查询用作表达式时,这是不允许的。

这是我的触发器:

 ALTER TRIGGER dbo.TriggerUpdateAdvert
 ON dbo.Advert FOR UPDATE
 AS
    DECLARE @OldStatus INT;
    DECLARE @NewStatus INT;
    DECLARE @ID UNIQUEIDENTIFIER;

    SET @ID=(SELECT I.ID_Advert FROM INSERTED I);
    PRINT @ID
    SET @OldStatus=(SELECT D.Status FROM DELETED D WHERE D.ID_Advert=@ID);
    SET @NewStatus=(SELECT I.Status FROM INSERTED I WHERE I.ID_Advert=@ID);


    IF(@OldStatus!=@NewStatus)
    BEGIN
    print @OldStatus
    print @NewStatus
        IF(@NewStatus=1 or @NewStatus=3)
        BEGIN
            UPDATE Advert SET Published_Date=GETDATE() WHERE ID_Advert=@ID
        END
    END


 GO

编辑:

我创建了下一个代码:

        UPDATE A
        SET A.Published_Date=GETDATE()
        FROM Advert A
        INNER JOIN Inserted I ON A.ID_Advert=I.ID_Advert
        INNER JOIN Deleted D ON D.ID_Advert=A.ID_Advert
        WHERE I.Status!=D.Status  AND (I.Status IN (1,3) AND D.Status NOT IN (1,3)) 

你有什么想法吗?

【问题讨论】:

  • 您的主要缺陷是您假设触发器将每行调用一次 - 它不是!它将被调用每个语句一次Inserted 伪表可以包含多行 - 所以在这种情况下 - 你在这里选择多行中的哪一个??? SET @ID=(SELECT I.ID_Advert FROM INSERTED I); ....您需要重写您的触发器以考虑多行并适当地处理它们!

标签: sql-server tsql triggers sql-update


【解决方案1】:

避免在触发器中使用 PRINT。

并像这样定义它:

 ALTER TRIGGER dbo.TriggerUpdateAdvert
 ON dbo.Advert FOR UPDATE
 AS
   UPDATE Advert SET Published_Date=GETDATE() 
   WHERE ID_Advert IN (
     SELECT i.id 
     FROM inserted i 
     INNER JOIN deleted d 
     ON i.ID_Advert = d.ID_Advert
     WHERE i.Status <> d.Status
     AND i.Status IN (1,3)
   )
 END

【讨论】:

    【解决方案2】:
    UPDATE a SET Published_Date = CURRENT_TIMESTAMP
      FROM dbo.Advert AS a
      INNER JOIN inserted AS i ON a.ID_Advert = i.ID_Advert
      INNER JOIN deleted AS d  ON i.ID_Advert = d.ID_Advert
      WHERE i.Status IN (1,3) AND d.Status <> i.Status;
    

    【讨论】:

    • @Otix 抱歉,由于某种原因我没有看到编辑,我想我正坐在这个问题上并没有注意到它进来。所以你添加了编辑,还有问题吗这里?那不可能产生您最初报告的错误消息,那么您在这里寻找其他什么想法?
    • 其实我正在寻找最快/最好的方法....如果这是唯一的方法就可以了。我会用这个方法
    • 我认为您不会找到任何更快的方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-05-24
    • 1970-01-01
    • 2012-02-02
    • 2010-10-14
    • 1970-01-01
    • 1970-01-01
    • 2018-04-15
    相关资源
    最近更新 更多