我的触发器有问题(添加和删除):
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。当子查询遵循=,!=,<,< =,>,> =或子查询用作表达式时,不允许这样做。
怎么可能?
感谢您的帮助
答案 0 :(得分:2)
如果insert或delete语句应插入或删除多行,则两个触发器都不起作用。你需要停止假设你的触发器只处理一行 - 事实并非如此。您需要重写触发器以同时处理多个行(在Inserted
和Deleted
表中)
作为一个例子 - 您可以重写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语句返回多个值,因此触发器会抛出该异常。