【发布时间】:2020-02-12 12:10:42
【问题描述】:
我有一个表 ice_cream 有两列 primary_key user_id 和 int counter,默认值为 0。
我想插入一个带有counter 值1 的user_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