9

スラッグ値を含むテーブルを、レコードごとにランダムなスラッグで更新しようとしています。

$vouchers = Voucher->get(); // assume 10K for example

foreach ($vouchers as $voucher) {
    $q .= "UPDATE vouchers set slug = '" . Str::random(32) . "' WHERE id = " . $voucher->id . ";";
}

DB::statement($q);

約 200 万件のレコードがあるため、これをまとめて実行する必要があります。別々のレコードとしてそれを行うには時間がかかりすぎます。10K のグループなど、それらを一括実行する方法が見つからないようです。

->update()andのさまざまなバリエーションを試してみましたDB::statementが、うまくいかないようです。

4

4 に答える 4

5

私のように誰かがこのページにアクセスした場合、laravel は次のように一括更新を許可します。

$affectedRows = Voucher::where('id', '=', $voucher->id)->update(array('slug' => Str::random(32)));

http://laravel.com/docs/4.2/eloquent#insert-update-deleteの「取得したモデルの更新」を参照してください

于 2014-12-18T14:18:15.197 に答える
3

update_batchのように、複数の更新用に My Custom 関数を作成しましたCodeIgniter

この関数をモデルのいずれかに配置するか、ヘルパー クラスを作成してそのクラスにこの関数を配置することができます。

//test data
/*
$multipleData = array(
   array(
      'title' => 'My title' ,
      'name' => 'My Name 2' ,
      'date' => 'My date 2'
   ),
   array(
      'title' => 'Another title' ,
      'name' => 'Another Name 2' ,
      'date' => 'Another date 2'
   )
)
*/

/*
 * ----------------------------------
 * update batch 
 * ----------------------------------
 * 
 * multiple update in one query
 *
 * tablename( required | string )
 * multipleData ( required | array of array )
 */
static function updateBatch($tableName = "", $multipleData = array()){

    if( $tableName && !empty($multipleData) ) {

        // column or fields to update
        $updateColumn = array_keys($multipleData[0]);
        $referenceColumn = $updateColumn[0]; //e.g id
        unset($updateColumn[0]);
        $whereIn = "";

        $q = "UPDATE ".$tableName." SET "; 
        foreach ( $updateColumn as $uColumn ) {
            $q .=  $uColumn." = CASE ";

            foreach( $multipleData as $data ) {
                $q .= "WHEN ".$referenceColumn." = ".$data[$referenceColumn]." THEN '".$data[$uColumn]."' ";
            }
            $q .= "ELSE ".$uColumn." END, ";
        }
        foreach( $multipleData as $data ) {
            $whereIn .= "'".$data[$referenceColumn]."', ";
        }
        $q = rtrim($q, ", ")." WHERE ".$referenceColumn." IN (".  rtrim($whereIn, ', ').")";

        // Update  
        return DB::update(DB::raw($q));

    } else {
        return false;
    }
}

それは生成します:

UPDATE `mytable` SET `name` = CASE
WHEN `title` = 'My title' THEN 'My Name 2'
WHEN `title` = 'Another title' THEN 'Another Name 2'
ELSE `name` END,
`date` = CASE 
WHEN `title` = 'My title' THEN 'My date 2'
WHEN `title` = 'Another title' THEN 'Another date 2'
ELSE `date` END
WHERE `title` IN ('My title','Another title')
于 2014-12-18T05:43:04.123 に答える
-1

結果のチャンク化は、RAM をすべて消費することなくこの種のことを行うための最良の方法であり、Laravel はすぐに結果のチャンク化をサポートします。

例えば:

  Voucher::chunk(2000, 関数($バウチャー)
  {
    foreach ($voucher としての $voucher)
    {
        ///
    }
 });
于 2014-10-01T05:30:03.560 に答える