MySQL INSERT IF(自定义if语句)
首先,下面是问题的简要总结:
是否有可能有条件地运行INSERT
语句? 类似这样的东西:
IF(expression) INSERT...
现在,我知道我可以用存储过程来做到这一点。 我的问题是:我可以在我的查询中做到这一点?
现在,我为什么要这样做呢?
假设我们有以下两个表格:
products: id, qty_on_hand orders: id, product_id, qty
现在,让我们来说20个巫毒娃娃(产品编号2)的订单进来。
我们首先检查手头是否有足够的数量:
SELECT IF( ( SELECT SUM(qty) FROM orders WHERE product_id = 2 ) + 20 <= ( SELECT qty_on_hand FROM products WHERE id = 2) , 'true', 'false');
然后,如果它评估为真,我们运行一个INSERT
查询。
到现在为止还挺好。
但是,并发性有问题。
如果两个订单在同一时间进入,他们可能都会在其中任何一个订单进入之前阅读手头数量。 然后他们会下订单,从而超过qty_on_hand
。
所以,回到问题的根源:
是否可以有条件地运行INSERT
语句,以便我们可以将这两个查询合并为一个?
我search了很多,我能find的唯一一种条件INSERT
语句是ON DUPLICATE KEY
,这在这里显然不适用。
INSERT INTO TABLE SELECT value_for_column1, value_for_column2, ... FROM wherever WHERE your_special_condition
如果select没有返回行(因为你的特殊条件是false),不会发生插入操作。
从问题中使用你的模式(假设你的id
列是auto_increment
):
insert into orders (product_id, qty) select 2, 20 where (SELECT qty_on_hand FROM products WHERE id = 2) > 20;
如果没有足够的库存,这将不插入行,否则将创build订单行。
好想法btw!
尝试:
INSERT INTO orders(product_id, qty) SELECT 2, 20 FROM products WHERE id = 2 AND qty_on_hand >= 20
如果存在id
等于2
产品,且此产品的qty_on_hand
大于或等于20
,则插入操作将以product_id = 2
和qty = 20
的值发生。 否则,不会发生插入。
注意 :如果您的产品ID是唯一的注释,您可能需要在SELECT
语句的末尾添加一个LIMIT
子句。
你可能错误地解决了这个问题。
如果担心两个读操作会同时发生,那么就会使用陈旧的数据,解决scheme是使用锁或事务 。
有查询这样做:
- 锁表读取
- 读表
- 更新表
- 释放locking
不确定并发性,你需要阅读关于在MySQL中locking,但是这将让你确保只有20个项目,如果20个项目可用:
update products set qty_on_hand = qty_on_hand - 20 where qty_on_hand >= 20 and id=2
然后您可以检查有多less行受到影响。 如果没有影响,你没有足够的股票。 如果1行受到影响,您已经有效地消耗了股票。