Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
mySQL:在一个查询中处理选择和更新?_Mysql_Sql - Fatal编程技术网

mySQL:在一个查询中处理选择和更新?

mySQL:在一个查询中处理选择和更新?,mysql,sql,Mysql,Sql,在mySQL表inv中有3列:ID、num和state。 状态有3个值:0=未使用,1=已使用,2=保留。 要获取下一个未使用的num,我使用以下查询: SELECT num FROM inv WHERE state = 0 当查询返回num时,我需要更新记录并将状态设置为2=保留 UPDATE inv SET state = 2 Where ID = id 我知道只有一个查询可以做到这一点,但是如何做到呢 任何有帮助的回答都将不胜感激 编辑: 我正在努力做到这一点: 我需要生成具有

在mySQL表inv中有3列:ID、num和state。 状态有3个值:0=未使用,1=已使用,2=保留。 要获取下一个未使用的num,我使用以下查询:

SELECT num FROM inv WHERE state = 0   
当查询返回num时,我需要更新记录并将状态设置为2=保留

UPDATE inv SET state = 2 Where ID = id 
我知道只有一个查询可以做到这一点,但是如何做到呢

任何有帮助的回答都将不胜感激

编辑:

我正在努力做到这一点:

我需要生成具有唯一编号的发票。因此,我获取下一个状态为0的空闲、未使用的数字,然后返回这个数字,并在同一个查询中将返回的记录设置为状态为2,这样其他人就不会同时使用它。后来,当我成功生成一张完美的发票时,我用state=1 used更新了该记录。如果生成无缺陷发票失败,我将状态设置回0=未使用

希望我能更清楚地表达我的方法。

这样行吗

UPDATE inv SET state = 2 Where ID IN (SELECT id FROM inv WHERE state = 0)
更新库存设置状态=2,其中id在从库存位置选择id中 状态=0限制1

这将获取下一个num值并将其更新为reserved

最新答复:

对于给出的错误答案,我深表歉意,因为上面所说的查询将不起作用,因为limit子句仅限于在MySQL中与子查询一起使用

因此,我提出了另一种类似于这里给出的答案的方法:

此查询已通过示例数据验证。

尝试此操作

SET @num = null;
SET @id = null;
SELECT id into @id FROM inv WHERE state = 0 LIMIT 1;
SELECT num into @num FROM inv WHERE id = @id;

PREPARE stmt FROM 'UPDATE inv SET state = 2 Where ID = ?' USING @id;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

SELECT @num;

如果存在,为什么不使用?这可能会容易得多。您可能会找到它,或者为什么不将其包含在where子句中。您最好使用存储过程来获取num,更新它,然后返回它,但您也会受到竞争条件的影响,因此要小心并发性。您最好解释您试图解决的问题,而不是数据库的当前状态。请参阅上面的我的编辑。-1的作用是什么?您也可以只更新inv SET state=2,其中state=0。我很确定OP是从第一个查询中选择第一个返回行,然后在第二个查询中更新它。哦,当然,这很简单。如果我正确理解OP的问题,他应该这么做。是的,但可能不是,这就是问题所在。问题不是很清楚,但我很确定他希望更新一条记录。如果你在子选择中添加限制1,应该可以。随着时间的推移,可能会累积更多state=0的记录。请参阅上面我的编辑。我需要找到状态为0的第一条记录。其他人则不感兴趣。那么限制是什么呢?b不仅没有列id,而且这也是错误的。请参阅我对@hashbrown答案的评论。虽然您的建议可能解决了最初的问题,但一些关于您的建议如何解决问题的解释可能有助于在稍后与OP和其他读者更好地了解答案。这肯定以当前的形式回答了问题。现在我没有亲自提供这个的原因是因为我打赌5美元,他们想知道哪一个刚刚更新,并将其返回到调用代码。但我可能对它读得太多了:-PReturns-FALSE。语句在何处返回数字?代表联接操作数的select查询将返回一个ID,并根据该ID,动态更新status列。这是通过单行查询可以实现的。清楚你想做什么,更新还是获取一个数字?如果你读了我上面的问题,上面写着:获取下一个未使用的数字。这有什么不清楚的?再次:我需要获取一个数字,将状态设置为2,在发票中使用它,并在无缺陷发票生成后更新记录状态1。所以,获取它并将状态设置为2我想在一个语句事务中执行。对于您的要求,单行查询不是正确的方法。您应该在MySQL中使用存储过程或触发器来实现结果。参考@Reno提供的答案如何用PDO表达?
update inv a join (select id, num from inv where state=0 limit 1) b
 on a.id = b.id SET state=2;
SET @num = null;
SET @id = null;
SELECT id into @id FROM inv WHERE state = 0 LIMIT 1;
SELECT num into @num FROM inv WHERE id = @id;

PREPARE stmt FROM 'UPDATE inv SET state = 2 Where ID = ?' USING @id;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

SELECT @num;