首先,以下是问题的简要总结:

可以有条件地运行INSERT语句吗?

IF(expression) INSERT...

现在,我知道我可以用存储过程来实现这一点.


我为什么要这么做?

假设我们有以下两个表:

products: id, qty_on_hand
orders: id, product_id, qty

Now, let's say an order for 20 Voodoo Dolls (product id 2) comes in.
We first check if there's enough Quantity On Hand:

SELECT IF(
    ( SELECT SUM(qty) FROM orders WHERE product_id = 2  ) + 20
    <=
    ( SELECT qty_on_hand FROM products WHERE id = 2)
, 'true', 'false');

Then, if it evaluates to true, we run an INSERT query.
So far so good.


However, there's a problem with concurrency.
If 2 orders come in at the exact same time, they might both read the quantity-on-hand before any one of them has entered the order. They'll then both place the order, thus exceeding the qty_on_hand.


So, back to the root of the question:
Is it possible to run an INSERT statement conditionally, so that we can combine both these queries into one?

我搜索了很多,我能找到的唯一一种条件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;

如果手头没有足够的库存,这将不插入行,否则将创建订单行.

好主意!

Mysql相关问答推荐

同一类型对象之间的多对多关系

嵌套MySQL语句问题

无条件理解MySQL中内连接和交叉连接的相似性

在MySQL和JavaFX中保存和检索图像文件

MySQL多次联接同一个表使计数变得奇怪

从表中 Select 具有不同顺序的列

MySQL:获取连续记录的数量(日期)?

查询优化并提高性能

MySQL中的where语句会 destruct 全外连接.

MySQL - 如何根据单列查找重复行?

根据 Power Query 中的条件替换值

将 AVG 与 HAVING 结合使用

在 where 子句中左连接多个值

SQL 查找边界之间的值

使用case查询并更新最后一条记录

重新加载 .env 变量而不重新启动服务器(Laravel 5,共享主机)

phpmyadmin没有收到要导入的数据错误,如何解决?

MySQL - 表'my_table'没有被锁定表锁定

Doctrine2 迁移向下迁移并从浏览器而不是命令行迁移

MySQL - 重复表