一个有关 decrement 和 increment 的问题

先说一下问题出现的场景

我是用的数据库是mysql, 表里面有一个虚拟币的字段, 某些情况下需要去减这个字段, 我都是使用 decrementdecrement 这两个方法取操作的, 数据库对这个字段设置的是 无符号, 也就是大于0的

XxModel::where(xxx)->decrement('sum', 20); //是这么操作的

一般情况下是正常的, 但是今天的情况是, 我的账户虚拟币 还有20个, 但是我代码减去100

XxModel::where(xxx)->decrement('sum', 100);

问题就出现了, 这个代码返回的值是1, 数据库字段值变成0, 这是什么情况?

后来我又尝试了以下的方法, 但是得到的结果都一致

DB::table('xxx')->where(xxx)->decrement('sum', 100);
DB::table('xxx')->where(xxx)->update(['sum' =>  DB::raw('sum - 100')]);
XxModel::where(xxx)->first()->decrement('sum', 100);

我在数据库执行

update table set sum = sum - 100 where xxx

会出现报错信息

Out of range value for column 'sum' at row 123016, Time: 0.089000s

所以laravel 的 decrement 是怎么算的呢

ruke
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
最佳答案

decrement执行的是update,返回的是执行成功是受影响的行数,而不是最后的结果。
在你你使用:update table set sum = sum - 100 where xxx会出现:BIGINT UNSIGNED value is out of range in的错误信息,这个错误信息和实际的意义是一样的。
但是你执行:update table set sum = -80 where xxx时是可以执行成功的。执行结果就是0,这可能是mysql机制问题。
decrement使用Update

        $wrapped = $this->grammar->wrap($column);
        $columns = array_merge([$column => $this->raw("$wrapped - $amount")], $extra);
        return $this->update($columns);

1、提前判断是剩余的数量是否够扣除。
2、可以使用原生sql
3、建议在数据库中,这个值最好不要设置成无符号型字段,应该可以为负数,你可以理解成用户透支,也可以做到出与入的统一。

4年前 评论
讨论数量: 3

返回的是受影响的行数吧

4年前 评论
Epona

unsigned 最小值是0, 无法变成负数的。

4年前 评论

decrement执行的是update,返回的是执行成功是受影响的行数,而不是最后的结果。
在你你使用:update table set sum = sum - 100 where xxx会出现:BIGINT UNSIGNED value is out of range in的错误信息,这个错误信息和实际的意义是一样的。
但是你执行:update table set sum = -80 where xxx时是可以执行成功的。执行结果就是0,这可能是mysql机制问题。
decrement使用Update

        $wrapped = $this->grammar->wrap($column);
        $columns = array_merge([$column => $this->raw("$wrapped - $amount")], $extra);
        return $this->update($columns);

1、提前判断是剩余的数量是否够扣除。
2、可以使用原生sql
3、建议在数据库中,这个值最好不要设置成无符号型字段,应该可以为负数,你可以理解成用户透支,也可以做到出与入的统一。

4年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!