【问题标题】:laravel eloquent ignore error when inserting a duplicate key插入重复键时,laravel eloquent 忽略错误
【发布时间】:2017-10-16 06:29:29
【问题描述】:

我正在从另一个服务获取 JSON,并希望在表中插入一堆数据。我想以一种每次运行时都不会崩溃的方式来做。我想在我的表的 PK 上保留我的唯一约束,(因为我不想两次插入相同的数据)但是,如果发生这种情况,我不希望 laravel 抛出致命错误(仅在特定表上)。

如何插入我的数据,如果我尝试插入另一个具有重复主键的数据,我该如何继续插入?

Schema::create('dummy', function (Blueprint $table) {
    $table->integer('id')->unique();

    $table->string('name',100);
});

从另一个 API 获取一堆 JSON。然后插入所有行:

{ 
   'id':1,
    'name': 'one'
},{
    'id':2
    'name':'two'
}

这样。

DB::table('dummy')->insert([
    ['id' => 1, 'name' => 'one'],
    ['id' => 2, 'name' => 'two']
]);

再过一天,第 3 方 API 上有新数据。并想更新我的数据库:

获取 json,并接收:

{ 
   'id':1,
    'name': 'one'
},{
    'id':2
    'name':'two'
},{
    'id':3
    'name':'three'
}

这使得:

DB::table('dummy')->insert([
    ['id' => 1, 'name' => 'one'], // <-- will crash there cause PK already existe, but want to keep inserting
    ['id' => 2, 'name' => 'two'], // <-- skipp cause already exist
    ['id' => 3, 'name' => 'three'] // insert that line.
]);

【问题讨论】:

  • 您要么想出一个处理重复项的自定义查询(例如 ON DUPLICATE KEY UPDATE)——以提高效率。或者,您将在表中插入数据的代码段包装在 try { ... } catch(\Exception $e) { // 出现问题。 }
  • @tadman 我虽然很清楚
  • 这有点具体,但如果你包含一个小sn-p代码来演示问题,那将是非常清楚的。
  • @tadman 更新了 OP
  • 这用非常精确的术语来说明。不错!

标签: php mysql laravel eloquent


【解决方案1】:

Laravel 的查询构建器现在在 v5.8.33 及更高版本中具有 insertOrIgnore

<?php
DB::table('users')->insertOrIgnore([
    ['id' => 1, 'email' => 'taylor@example.com'],
    ['id' => 2, 'email' => 'dayle@example.com']
]);

在此处阅读更多信息:https://laravel.com/docs/5.8/queries#inserts


请注意,insertOrIgnore 将忽略重复记录,也可能会忽略其他类型的错误,具体取决于数据库引擎。例如,insertOrIgnore 将绕过 MySQL 的严格模式。

【讨论】:

  • 这是否适用于带有 Model:createOrIgnore() 的模型?在你说使用 firstOrCreate 之前,它具有糟糕的竞争条件适用性。
  • 谢谢@Jared
【解决方案2】:

你可以尝试捕捉 PDO 异常

try 
{
    // inserting in DB;
}
catch(\Illuminate\Database\QueryException $e){
    // do what you want here with $e->getMessage();
}

或者,但不确定,您可以尝试使用数据库事务:

public function insertInDB()
{
    DB::transaction(function () {
        DB::table(...);
        // if everything is fine, it will commit, else, it will rollback
    }
}

【讨论】:

    【解决方案3】:

    您想要的是INSERT IGNORE,并且该问题已经得到解答,请参阅INSERT IGNORE using Laravel's Fluent

    【讨论】:

      猜你喜欢
      • 2011-09-24
      • 2016-10-22
      • 2010-10-23
      • 2018-02-02
      • 1970-01-01
      • 1970-01-01
      • 2021-05-02
      • 1970-01-01
      • 2020-07-16
      相关资源
      最近更新 更多