嗯,在SQL server 2012中,我有一个表来跟踪……好吧,项目..。
Storage表基本上有Capacity和Filled两个列,每次Item表有变化都需要更新Filled列,但不能高于Capacity值,也不能小于0。我试着把这一切都放在一个扳机里...我希望到目前为止我说的有道理。这就是我试图做的,并且我认为触发器只在INSERT发生时被激活……
ALTER TRIGGER [dbo].[CapCheck]
ON [dbo].[Item]
AFTER INSERT, DELETE, UPDATE
AS
BEGIN
DECLARE @Amount int
DECLARE @S_ID int
SELECT @Amount = Amount, @S_ID = S_ID
FROM inserted
IF @Amount = NULL
BEGIN
SELECT @Amount = -(Amount), @S_ID = S_ID
FROM deleted
END
DECLARE @Filled int
DECLARE @Capacity int
SELECT @Filled = Filled, @Capacity = Capacity
FROM Storage
WHERE S_ID = @S_ID
SET @Filled = @Filled + @Amount
IF @Capcaity < @Filled OR @Filled < 0
BEGIN
ROLLBACK TRANSACTION
END
ELSE
BEGIN
UPDATE Storage
SET Filled = @Filled
WHERE S_ID = @S_ID
END
END任何建议都是非常感谢的,你们是最好的
发布于 2014-01-25 17:31:22
您的基本缺陷是您似乎期望触发器每行触发一次-这是,而不是SQL Server中的情况。相反,触发器为每个语句触发一次,并且伪表Inserted可能包含多行。
假设该表可能包含多行-您希望在此处选择哪一行??
SELECT @Amount = Amount, @S_ID = S_ID
FROM inserted 它是未定义的-您可能会从Inserted中的任意行获得值。
您需要重写整个触发器,以了解Inserted 将包含多行!您需要使用基于集合的操作-不要期望在Inserted中只有一行!
另外:我强烈建议为每个操作编写单独的触发器-为INSERT编写一个触发器,为DELETE编写一个触发器,为UPDATE编写一个触发器。这将使触发器代码变得容易得多(因为您不必对正在处理的操作类型进行太多检查)。
https://stackoverflow.com/questions/21344385
复制相似问题