【问题标题】:How to mass insert or update in a single query (not a for loop of queries) using Laravel 4.2如何使用 Laravel 4.2 在单个查询(不是 for 查询循环)中批量插入或更新
【发布时间】: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 不是我的强项。
  • @M0riis:感谢您的链接。我去看看。
  • @M0riis:我尝试通过 Eloquent 和/或 Fluent 的一个原因是因为 Laravel 会检查这些值是否有效,所以进行注入攻击要困难得多。

标签: php mysql laravel eloquent fluent


【解决方案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 的用户名?
  • 这篇文章可能很有趣stackoverflow.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 行或更多行的示例?
    • 可以批量操作吗?好像只有单身
    猜你喜欢
    • 2019-09-29
    • 1970-01-01
    • 1970-01-01
    • 2013-03-15
    • 1970-01-01
    • 2013-10-14
    • 2016-06-30
    • 2021-10-02
    • 2016-08-06
    相关资源
    最近更新 更多