一个有关 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
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
最佳答案

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、建议在数据库中,这个值最好不要设置成无符号型字段,应该可以为负数,你可以理解成用户透支,也可以做到出与入的统一。

1周前 评论
讨论数量: 3

返回的是受影响的行数吧

1周前 评论
Epona

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

1周前 评论

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、建议在数据库中,这个值最好不要设置成无符号型字段,应该可以为负数,你可以理解成用户透支,也可以做到出与入的统一。

1周前 评论

请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!

社区文档:

将托管在 packagist.org 和 github.com 的扩展包使用国内 CDN 加速
GitHub Laravel 扩展包 TOP 250
速查表方便快速查询框架功能,支持手机访问,支持中英文版本
Laravel 中文文档,由社区用户翻译和维护,将会保持一直更新
此文档的目的,就是为了提高技术团队的凝聚力、一致性和生产效率。
开发环境的部署,开发者工具的选择,适用于 Mac 和 Windows。
浓缩过后的精华
Laravel Nova 后台管理面板文档的中文翻译
Lumen 中文文档,由社区用户翻译和维护,将会保持一直更新
Laravel 下知名扩展包 Dingo API 的中文文档,Laravel API 开发必知必会