【问题标题】:Increment column on duplicate for SQLite & MySQLSQLite 和 MySQL 的重复列增量
【发布时间】:2020-02-12 12:10:42
【问题描述】:

我有一个表 ice_cream 有两列 primary_key user_id 和 int counter,默认值为 0。

我想插入一个带有counter1user_id,并在重复时增加counter

我正在寻找适用于 MySQL 和 SQLite 的 Laravel Database Builder 5.6 版解决方案。

对于 MySQL,我有这个解决方案:

 IceCream::updateOrCreate([
                    'user_id' => $user_id,
    ],
    [
       'counter' =>  \DB::raw('counter + 1'),
    ]);

但是,这不适用于 SQLite。我收到以下错误消息:

Illuminate\Database\QueryException: SQLSTATE[HY000]: 一般错误:1 没有这样的列:计数器(SQL:插入“ice_cream”(“user_id”, "counter") 值 (12,counter + 1))

对于 SQLite,我还有一个自定义解决方案:

\DB::select(\DB::raw('INSERT OR IGNORE INTO ice_cream (user_id,counter) VALUES (?,0) '), [$user_id]);
\DB::select(\DB::raw("UPDATE ice_cream SET counter = counter + 1 WHERE user_id= ?"), [$user_id]);

但是这不适用于 MySql。

自 Laravel 版本 v5.8.33 以来,有一个通用的 insertOrIgnore 方法,但是我目前使用的是 Laravel v5.6,目前无法进行更新。

是否可以创建一种适用于两者的解决方案?

【问题讨论】:

  • 你试过用反引号括起来字段名吗? \DB::raw('`counter` + 1') kysql 和 sqlite 都使用反引号作为标识符名称。
  • @Shadow 谢谢你的想法,我试过了,但我仍然得到同样的错误
  • @CPerkins 是的,谢谢你的提示,我已经更正了。
  • 我不熟悉 laravel,但这是 laravel 的 sqlite 实现中的错误吗?从 mysql 切换到 sqlite 时,您是否真的更改了库和/或设置了一个指示后端类型的标志?我问,因为必须为 MySQL 生成类似于您的 sqlite 自定义解决方案的东西,才能正确处理新插入与更新。你能得到为mysql生成的命令/脚本来比较吗?例如,mysql 支持INSERT IGNORE,而 sqlite 需要INSERT OR IGNORE,奇怪的是它不能在两者之间正确选择。
  • @CPerkins 我不认为它是一个错误,我认为它只是不受支持。我有一个环境文件,在那里我可以更改 database_driver。对于测试,我想要 SQLite,因为它更快。 MySQL 查询与用于插入的 SQLite 查询相同,它们都得到 nsert into "ice_cream" ("user_id", "counter") values (12,counter + 1) 但它仅适用于 MySQL。 insertOrIgnore 仅从 Laravle v5.8.33 开始工作。

标签: php mysql sqlite laravel-5


【解决方案1】:

找到一种适用于 MySQL 和 SQLite 的方法:

$iceCream = static::firstOrNew([
                'user_id' => $user_id,
            ], 
            ['counter' => 0]);

$iceCream->counter++;

$iceCream->save();

【讨论】:

    猜你喜欢
    • 2013-09-15
    • 2012-11-01
    • 1970-01-01
    • 2014-12-09
    • 2023-02-17
    • 1970-01-01
    • 1970-01-01
    • 2016-03-19
    相关资源
    最近更新 更多