web-dev-qa-db-ja.com

Laravel複数の行を挿入または更新する

私はlaravelで新しく、ナビゲーションツリーを更新しようとしています。したがって、foreachなしで1つのクエリでツリー全体を更新したいと思います。

array(
  array('id'=>1, 'name'=>'some navigation point', 'parent'='0'),
  array('id'=>2, 'name'=>'some navigation point', 'parent'='1'),
  array('id'=>3, 'name'=>'some navigation point', 'parent'='1')
);

私は尋ねたいだけです-laravel to insert(in new in array))or update my current rows in database?

ツリーに_lft、_right、parent_idというフィールドがあり、ドラッグ可能なjsプラグインを使用してナビゲーション構造を設定しているので、すべてを更新したいので、保存します。

使ってみた

Navigation::updateOrCreate(array(array('id' => '3'), array('id'=>'4')), array(array('name' => 'test11'), array('name' => 'test22')));

しかし、それは私がやろうとしたような複数ではなく、単一の行に対してのみ機能します。多分それを行う別の方法がありますか?

8
Mateusz Kudej

Laravelコア(今日まで)でこの種の機能がまだ利用できないのはなぜでしょうか。チェックしてください this Gist クエリ文字列の結果は次のようになります。 ここ

リンクが将来切れた場合に備えて、ここにコードを入れています。私は作成者ではありません。

/**
* Mass (bulk) insert or update on duplicate for Laravel 4/5
* 
* insertOrUpdate([
*   ['id'=>1,'value'=>10],
*   ['id'=>2,'value'=>60]
* ]);
* 
*
* @param array $rows
*/
function insertOrUpdate(array $rows){
    $table = \DB::getTablePrefix().with(new self)->getTable();


    $first = reset($rows);

    $columns = implode( ',',
        array_map( function( $value ) { return "$value"; } , array_keys($first) )
    );

    $values = implode( ',', array_map( function( $row ) {
            return '('.implode( ',',
                array_map( function( $value ) { return '"'.str_replace('"', '""', $value).'"'; } , $row )
            ).')';
        } , $rows )
    );

    $updates = implode( ',',
        array_map( function( $value ) { return "$value = VALUES($value)"; } , array_keys($first) )
    );

    $sql = "INSERT INTO {$table}({$columns}) VALUES {$values} ON DUPLICATE KEY UPDATE {$updates}";

    return \DB::statement( $sql );
}

したがって、次のように配列を安全に挿入または更新できます。

insertOrUpdate(
    array(
      array('id'=>1, 'name'=>'some navigation point', 'parent'='0'),
      array('id'=>2, 'name'=>'some navigation point', 'parent'='1'),
      array('id'=>3, 'name'=>'some navigation point', 'parent'='1')
    )
);

関数の最初の行で問題が発生した場合に備えて、テーブル名を2番目の引数として追加し、次の行をコメント化できます。

function insertOrUpdate(array $rows, $table){
    .....
}

insertOrUpdate(myarrays,'MyTableName');

注意:入力を無害化するように注意してください!また、タイムスタンプフィールドは変更されません。メインアレイの各アレイに手動で追加することでそれを行うことができます。

雄弁なスタイル

public function meta(){ // in parent models.
    return $this->hasMany('App\Models\DB_CHILD', 'fk_id','local_fk_id');
}

。 。 。

$parent= PARENT_DB::findOrFail($id);
$metaData= [];
        foreach ($meta['meta'] as $metaKey => $metaValue) {

            if ($parent->meta()->where([['meta_key', '=',$metaKey]] )->exists()) { 
                $parent->meta()->where([['meta_key', '=',$metaKey]])->update(['meta_value' => $metaValue]);
            }else{
                $metaData[] = [
                    'FK_ID'=>$fkId,
                    'meta_key'=>$metaKey,
                    'meta_value'=> $metaValue
                ];
            }

        }
$Member->meta()->insert($metaData);
2
Xebio

すべてのデータベース用のUPSERTパッケージを作成しました: https://github.com/staudenmeir/laravel-upsert

DB::table('navigation')->upsert(
    [
        ['id' => 1, 'name' => 'some navigation point', 'parent' => '0'],
        ['id' => 2, 'name' => 'some navigation point', 'parent' => '1'],
        ['id' => 3, 'name' => 'some navigation point', 'parent' => '1'],
    ],
    'id'
);
0

コントローラでDBを使用します。パブリック関数arrDta(){

        $up_or_create_data=array(
            array('id'=>2, 'name'=>'test11'),
            array('id'=>4, 'name'=>'test22')

        );

        var_dump($up_or_create_data);
        echo "fjsdhg";

        foreach ($up_or_create_data as $key => $value) {
            echo "key  ".$key;
            echo "<br>";
            echo " id: ".$up_or_create_data[$key]["id"];
            echo "<br>";
            echo " Name: ".$up_or_create_data[$key]["name"];


        if (Navigation::where('id', '=',$up_or_create_data[$key]["id"])->exists()) {
            DB::table('your_table_ name')->where('id',$up_or_create_data[$key]["id"])->update(['name' => $up_or_create_data[$key]["name"]]);
        }else{
            DB::insert('insert into your_table_name (id, name) values (?, ?)', [$up_or_create_data[$key]["id"], $up_or_create_data[$key]["name"]]);
        }

        }
0
Borna

いいえ、できません。一度に複数の行をinsert()でき、同じupdate()条件を使用して複数の行をwhere()できますが、updateOrCreate()を使用する場合は、 foreach()ループを使用する必要があります。

0
Alexey Mezenin