Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/251.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
Php 如果计数器为正,则减少计数器_Php_Mysql_Sql - Fatal编程技术网

Php 如果计数器为正,则减少计数器

Php 如果计数器为正,则减少计数器,php,mysql,sql,Php,Mysql,Sql,我正在尝试实现一个简单的信用系统,因此在我的用户表中有一列“credits”,我想使用PHP/MySQL执行以下操作: if (credits >= 1) credits = credits - 1; else error(not_enough_credits); 是否可以在一个查询中执行此操作?显然,我可以对积分执行SELECT查询,如果该查询大于等于1,则执行UPDATE以将计数器减少1,但这可能会导致并发问题 UPDATE myTable SET credits =

我正在尝试实现一个简单的信用系统,因此在我的用户表中有一列“credits”,我想使用PHP/MySQL执行以下操作:

if (credits >= 1)  
  credits = credits - 1;
else 
  error(not_enough_credits);
是否可以在一个查询中执行此操作?显然,我可以对积分执行
SELECT
查询,如果该查询大于等于1,则执行
UPDATE
以将计数器减少1,但这可能会导致并发问题

UPDATE myTable SET credits = (credits - 1)  WHERE credits > 0
在这种情况下,where将像if一样工作。如果您提供一个有效的用户id,这对多个用户单独工作也很好

UPDATE myTable SET credits = (credits - 1)  WHERE id=12345 AND credits > 0
在这种情况下,where将像if一样工作。如果您提供一个有效的用户id,这对多个用户单独工作也很好

UPDATE myTable SET credits = (credits - 1)  WHERE id=12345 AND credits > 0

您可以使用
CASE
语句,如下所示:

UPDATE table1
SET credits = CASE WHEN credits >= 1 THEN credits-1 END

您可以使用
CASE
语句,如下所示:

UPDATE table1
SET credits = CASE WHEN credits >= 1 THEN credits-1 END

使用where子句的解决方案更好,因为假设您在信用上有一个索引,您就不需要触摸每一行并在查询执行期间给出case语句求值。@MikeBrant ah错过了索引部分。感谢您提供的指针。使用where子句的解决方案更好,因为假设您有一个学分索引,您就不需要在查询执行期间接触每一行并给出case语句求值。@MikeBrant ah错过了索引部分。谢谢你的指点。很有趣。如果计数器实际减少了,我如何从结果中读取呢?您可以在此查询后检查受影响的行数。您使用哪种API进行MySQL连接?方法取决于这一点,还有一件事需要记住,此更新将锁定所有信用为0的行。因此,如果您正在从应用程序执行此更新,并且该应用程序具有使用此进程的其他模块/进程,则只要执行此更新,这些进程就可能挂起。因此,最好的方法是停止应用程序并启动查询(如果可能的话)。这是错误的。如果此更新仅应用于一个用户的数据,它将不会锁定每一行。谢谢,我没有想到这一点,这非常有效!至于上面关于锁定的评论,据我所知,这取决于表结构的选择(MyISAM阻塞整个表,而InnoDB只逐行阻塞)。但幸运的是,这对我的应用程序来说不是问题。如果计数器实际减少了,我如何从结果中读取呢?您可以在此查询后检查受影响的行数。您使用哪种API进行MySQL连接?方法取决于这一点,还有一件事需要记住,此更新将锁定所有信用为0的行。因此,如果您正在从应用程序执行此更新,并且该应用程序具有使用此进程的其他模块/进程,则只要执行此更新,这些进程就可能挂起。因此,最好的方法是停止应用程序并启动查询(如果可能的话)。这是错误的。如果此更新仅应用于一个用户的数据,它将不会锁定每一行。谢谢,我没有想到这一点,这非常有效!至于上面关于锁定的评论,据我所知,这取决于表结构的选择(MyISAM阻塞整个表,而InnoDB只逐行阻塞)。但幸运的是,这对我的申请来说不是问题。