删除后删除触发器的值

时间:2012-09-28 14:45:27

标签: sql sql-server-2005

我的触发器有问题(添加和删除):

ALTER TRIGGER [trgAfterShoppingInserted]
ON [ShopingList] AFTER INSERT 
AS BEGIN
   DECLARE @cardId char(6), @points int, @userId int

   SET @cardId = (SELECT cardId FROM inserted)
   SET @points = (SELECT points FROM inserted)
   SET @userId = (SELECT userId from [Card] WHERE id = @cardId)
   IF @userId = 0
   BEGIN
   Update [Card]
   set points = points + @points
   where id =@cardId
   END
   ELSE
   Update [Card]
   set points = points + @points
   where id =@cardId OR
   userId = @userId
END


ALTER TRIGGER [trgAfterShoppingDeleted]
ON [ShopingList] AFTER DELETE 
AS BEGIN
   DECLARE @cardId char(6), @points int, @userId int

   SET @cardId = (SELECT cardId FROM inserted)
   SET @points = (SELECT points FROM inserted)
   SET @userId = (SELECT userId from [Card] WHERE id = @cardId)
   IF @userId = 0
   BEGIN
   Update [Card]
   set points = points - @points
   where id =@cardId
   END
   ELSE
   Update [Card]
   set points = points - @points
   where id =@cardId OR
   userId = @userId
END

问题出在SET @cardId..

错误是:

  

子查询返回的值超过1。当子查询遵循=,!=,<,< =,>,> =或子查询用作表达式时,不允许这样做。

怎么可能?

感谢您的帮助

2 个答案:

答案 0 :(得分:2)

如果insert或delete语句应插入或删除多行,则两个触发器都不起作用。你需要停止假设你的触发器只处理一行 - 事实并非如此。您需要重写触发器以同时处理多个行(在InsertedDeleted表中)

作为一个例子 - 您可以重写trgAfterShoppingDeleted这样的内容:

ALTER TRIGGER [trgAfterShoppingDeleted]
ON [ShopingList] AFTER DELETE 
AS BEGIN
   UPDATE [Card]
   SET points = points - i.points
   FROM Inserted i
   WHERE Card.id = i.id AND i.UserId = 0

   UPDATE [Card]
   SET points = points - @points
   FROM Inserted i
   WHERE i.UserId <> 0 AND (Card.id = i.id OR Card.userId = i.userId)
END

您需要考虑数据集 - 不要假设触发器伪表中有单行,也不要在触发器中执行RBAR(逐行激动行)处理

答案 1 :(得分:1)

deleted表包含作为给定DELETE语句的一部分删除的记录,如果DELETE条件与多条记录匹配,则可以包含多行。

这就是您的情况,当您尝试从包含多个记录的cardId表中选择deleted时,select语句返回多个值,因此触发器会抛出该异常。