【发布时间】:2021-07-07 08:53:24
【问题描述】:
我创建了一个触发器,每次我插入“发票”表时,它都会检查数量(订购的数量)是否高于其他表中可用的库存数量。 如果数量较高,则应打印库存不足并删除新插入的行。 它根本没有这样做。它只是插入行,并没有打印出任何消息。
create trigger testtrigger
on invoices
after insert
as
begin
declare @productID int
declare @quantity int
declare @stock int
select @stock = stock from Products where ProductID = @productID
select @productID = productid from inserted;
select @quantity = Quantity from inserted;
if @productID not in (1, 2, 3, 4, 5, 6)
begin
if @quantity > @stock
begin
Print N'Not enough Stock. Current Stock: ' + @stock
delete from Invoices where InvoiceID = @@IDENTITY
end
end
end
前 6 种产品不是有库存量的东西,它是一种服务,所以我不希望它在这些产品 ID 的订单上触发。
这只是检查更多事情的更大 If Else 的一部分(例如,如果数量少于库存,则更新剩余库存的 else 语句,但这是触发器的开始,它不起作用所以我想我从这里开始。
【问题讨论】:
-
您的触发器存在严重缺陷;它假设
INSERT只包含 1 行。那明显是错的。此外,通常情况下,您不会DELETE行,PRINT信息消息,您会THROW错误。 -
如果同一产品也插入了 2 行,会发生什么情况?如果 other 表的值是
20,并且插入的两个行的值都是15,那么两者都小于20,但是,您肯定没有库存中的30。有人会期望 other 表的(股票?)列应该同时更新。 -
如果我抛出而不是删除,它仍然会删除插入的行吗?我不确定如何更改它以适应批量插入:/有没有办法让它逐行读取插入?
-
"有没有办法让它逐行读取插入内容?" 不要那样做,触发器的影响应该是最小尽可能在 DML 声明上;遍历插入的数据对于性能来说是糟糕的。
-
"如果我使用 throw 而不是 delete,它还会删除插入的行吗?" 假设您
THROW的错误具有足够高的严重性并且正在自动处理回滚,或在您的TRY...CATCH是的。但是您在这里提出的问题会导致更多问题;你的想法有几个缺陷。
标签: sql sql-server tsql triggers