SQL Server 2008 - 对 INSERT 和 UPDATE 触发器使用局部变量
我已经解决这个问题有一段时间了,但没有任何效果。
问题是为 order_details 表创建一个 INSERT 和 UPDATE 触发器 (tr_check_qty),以仅允许库存数量大于或等于订购数量的产品订单。
CREATE TRIGGER tr_check_qty
ON order_details
FOR insert, update
AS
DECLARE @stock int
DECLARE @neworder int
SELECT @stock = quantity_in_stock FROM products
SELECT @neworder = quantity FROM inserted
IF @neworder > @stock
BEGIN
PRINT 'NO WAY JOSE'
ROLLBACK TRANSACTION
END
为了测试这个触发器,我们应该使用这个查询:
UPDATE order_details
SET quantity = 30
WHERE order_id = '10044'
AND product_id = 7
该查询选择一个只有 28 个Quantity_in_stock 的产品,它应该触发触发器。但是我的触发器没有触发并且它成功更新了表。
我怀疑触发器不喜欢局部变量,所以我尝试不使用局部变量:
(SELECT quantity FROM inserted) > (SELECT quantity_in_stock FROM products)
但这给了我一个错误。
任何帮助将不胜感激!
I've been tinkering away at this problem for a while, but nothing's working for me.
The question is to create an INSERT and UPDATE trigger (tr_check_qty) for the order_details table to only allow orders of products that have a quantity in stock greater than or equal to the units ordered.
CREATE TRIGGER tr_check_qty
ON order_details
FOR insert, update
AS
DECLARE @stock int
DECLARE @neworder int
SELECT @stock = quantity_in_stock FROM products
SELECT @neworder = quantity FROM inserted
IF @neworder > @stock
BEGIN
PRINT 'NO WAY JOSE'
ROLLBACK TRANSACTION
END
To test this trigger, we are supposed to use this query:
UPDATE order_details
SET quantity = 30
WHERE order_id = '10044'
AND product_id = 7
The query selects a product that has only 28 quantity_in_stock, which should trigger the trigger. But my trigger does not trigger and it updates the table successfully.
I had a suspicion that triggers don't like local variables, so I tried not using local variables:
(SELECT quantity FROM inserted) > (SELECT quantity_in_stock FROM products)
But this gave me an error.
Any help would be appreciated!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您假设只有单行插入或更新。
quantity_in_stock FROM products
没有谓词 - 大概它需要检查插入的productid 的库存水平?如果是的话,products
表的结构是什么? (目前,假设products
表中有不止一行,@stock
将从任意行分配一个值。这在快照隔离下不起作用。
要解决 #1 和 #2,您需要使用
productid
或其他方式将inserted
表加入到products
表中,并查看是否有任何行存在于inserted.quantity > products.quantity_in_stock
有关 #3 的一些想法,请阅读 此处讨论
You are assuming that there will only be a single row insert or update.
quantity_in_stock FROM products
has no predicate - presumably it needs to check the stock level of the inserted productid? If so what is the structure of theproducts
table? (At the moment@stock
will be assigned a value from an arbitrary row assuming more than one row in theproducts
table.This will not work under snapshot isolation.
To get around #1 and #2 you would need to JOIN the
inserted
table onto theproducts
table usingproductid
or whatever and see if any rows exist whereinserted.quantity > products.quantity_in_stock
For some ideas about #3 read the discussion here
您的触发器并不遥远,但实际上您可以使用 INSTEAD OF 触发器
创建测试数据
这“有效”(在该术语的损失意义上)
考虑 Martin 的意见,需要确定
quantity_in_stock
的productid
。现在这些都按预期工作......
并且为了解决马丁斯的第一点,这种方法更好:
Your trigger isn't far off, but really you could be using and INSTEAD OF trigger
Create Test Data
This 'Works' (in the lossest sense of the term)
Taking on board Martin's comments the
productid
for thequantity_in_stock
needed to be determined.These now all work as expected...
And to address Martins first point this approach is better:
另一种解决方案是使用而不是触发器,如下所示:
此触发器的行为与其他建议不同!此触发器将插入已履行的订单并忽略超出库存水平的订单,这可能不是必需的[事实上,在大多数情况下可能不是;您的应用程序想知道订单何时尚未保存到数据库!!!]
注意这只是一个插入,您需要创建一个不同的触发器来更新“插入”值需要更新而不是插入。
同样,在这个问题的范围之外还有其他考虑因素。您可能应该在插入订单时减少库存水平,并且您应该可能想要处理为同一产品插入多个详细信息行的情况。
An alternative solution is to use the instead of trigger, something like this:
This trigger behaves differently from the other suggestion! This trigger will insert orders that are fulfilled and ignore orders that exceed the stock level, this maynot be want is required [in fact it probably isn't in most situations; your application would want to know when an order hasn't been saved to the DB!!!]
Note this is just an insert you'd need to create a different trigger for update as the 'inserted' values would need to be updates not inserts.
Again there are other considerations outside of the scope of this question.. you should probably be reducing the stock level as the orders are inserted and you should be may want to handle situations where multiple detail rows are inserted for the same product.