2

アプリケーションで「category_name」に一意性制約を持つ「categories」という名前のテーブルがあり、「categories」に複数の行を挿入したいと考えています。

悪い解決策:

foreach($categories as $category) {
   Category::firstOrCreate(array('category_name' => $category['name']));
}

これは解決策になる可能性がありますが、これは良い方法ではありません。問題は、数百または数千のレコードがある場合、データベースに対して多くのクエリが行われることです。これは良くありません。

比較対象ソリューション

foreach($categories as $category){
    $cats[] = array('category_name' => $category['name']);
}
Category::insert($cats);

しかし、重複した「category_name」を挿入しようとすると、例外がスローされ、カテゴリ名は挿入されません。

使用できることはわかっていますINSERT IGNOREが、laravel ソリューションのビルドを探しています。

4

1 に答える 1

2

2番目のケースでは1つのクエリが実行されるため、SQLサーバーが一意の制約のために拒否するため、エラーをキャッチしてもデータは挿入されないため、不可能だと思います。Laravel では扱えないと思います。

おそらく、このようなものは、より迅速に解決するための妥協です:

foreach($categories as $category){
   $names[] = $category['name']
}

$dups = Category::whereIn('name', $names)->lists('name');

if ($dups) {
  // here you can log or display message that some categories won't be inserted
}

$namesIns = [];
$cat = [];
foreach($categories as $category){
    $item = ['category_name' => $category['name']];
    if (!in_array($category['name'], $dups) && !in_array($item, $cat)) {
      $cat[] = $item;
      $namesIns[] = $category['name'];
    }
}
Category::insert($cat);

$ids = Category::whereIn('name', $namesIns)->lists('id');
于 2014-10-26T10:30:19.557 に答える