如何使用 Laravel 4.2 在单个查询(不是 for 查询循环)中批量插入或更新
Posted
技术标签:
【中文标题】如何使用 Laravel 4.2 在单个查询(不是 for 查询循环)中批量插入或更新【英文标题】:How to mass insert or update in a single query (not a for loop of queries) using Laravel 4.2 【发布时间】:2015-10-16 04:03:38 【问题描述】:$cardQueryList = [];
foreach($cards as $cardName => $quantity)
$cardQueryList[] = [
'username' => $user->username,
'card_uid' => $card->uid,
'have_quantity' => $quantity
];
Collection::insert($cardQueryList);
即使行存在,上面的代码也会创建新行。我怎样才能做到这一点,如果该行存在,它会更新。如果它不创建行?一个雄辩或流利的答案是最佳的,但如果没有其他方法,我愿意接受。
我想使用单个查询进行大规模更新/插入。不是每条记录的查询循环。理想情况下,出于显而易见的原因,我想访问数据库一次。
我也已经查看了以下链接:
Insert a new record if not exist and update if exist, laravel eloquent
以上适用于单个记录更新/插入。如果我用 for 循环运行会很慢。我正在寻找一个允许在单个查询中进行大规模插入/更新的答案。
注意:我使用“username”和“card_uid”作为我的密钥。因此,基本上当我找到具有所述用户名和 card_uid 的行时,我想更新相应的行。否则创建一个新行。
【问题讨论】:
你知道如何用 raw-sql 做到这一点吗?不雄辩或查询构建器 @M0rtiis:这是个好问题。我需要一点时间才能弄清楚。 mysql 不是我的强项。 你应该阅读这个dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html @M0riis:感谢您的链接。我去看看。 @M0riis:我尝试通过 Eloquent 和/或 Fluent 的一个原因是因为 Laravel 会检查这些值是否有效,所以进行注入攻击要困难得多。 【参考方案1】:通常,您将使用的 sql 类型类似于以下内容:-
insert into `TABLE` ( `FIELD1`,`FIELD2`, `FIELD3` ) values ( 'VALUE1','VALUE2','VALUE3' )
on duplicate key
update
`FIELD1`='VALUE1',
`FIELD2`='VALUE2',
`FIELD1`='VALUE3';
我无法告诉你如何在 laravel 中使用它!糟糕 - 忘记更新部分中的字段名称
【讨论】:
我很感激您的回复!问题,当我使用“用户名”和“card_uid”作为我的密钥时,它将如何检查代码的关键部分?那么基本上是否存在带有 card_uid 的用户名? 这篇文章可能很有趣***.com/questions/28078484/…【参考方案2】:<?php
$valuesArray = [];
foreach( $cards as $cardName => $quantity )
$valuesArray[] = "('".$user->username."','".$card->uid."','".$quantity."')";
$db->query
(
"INSERT INTO `TABLE` ( `username`,`card_uid`, `have_quantity` ) VALUES ".implode( ',', $valuesArray )."
ON DUPLICATE KEY UPDATE `have_quantity` = VALUES(`have_quantity`);"
);
确保您在用户名和 card_uid 上有一个主键。也不要忘记转义值并仅在 $valuesArray 不为空时运行查询。
【讨论】:
【参考方案3】:如果您不希望重复,请让您的数据库架构阻止重复条目的输入。在这种情况下捕获错误并继续。
【讨论】:
感谢您的回复。你能举个例子说明你在代码中的意思吗?【参考方案4】:你可以试试这个:
Collection::firstOrNew([
'username' => $user->username,
'card_uid' => $card->uid,
'have_quantity' => $cards['quantity']
])
->save();
要使其正常工作,请在您的 Collection
模型中添加具有大量可分配字段名称的 $fillable
属性,例如:
protected $fillable = ['username', 'card_uid', 'have_quantity'];
【讨论】:
我的模型目前有这样的 $fillable 设置:protected $fillable = ['username', 'card_uid', 'have_quantity', 'want_quantity'];我不确定我是否在关注 save() 部分?您能否提供一个填充 2 行或更多行的示例? 可以批量操作吗?好像只有单身以上是关于如何使用 Laravel 4.2 在单个查询(不是 for 查询循环)中批量插入或更新的主要内容,如果未能解决你的问题,请参考以下文章
Laravel 5.2 查询生成器作为单个数组(不是 2D 或 3D)
laravel的多态关联--morphTo和morphMany