Как массово вставить или обновить в одном запросе (не для цикла запросов), используя Laravel 4.2

$cardQueryList = [];
foreach($cards as $cardName => $quantity) {
    $cardQueryList[] = [
        'username' => $user->username,
        'card_uid' => $card->uid,
        'have_quantity' => $quantity
    ];
}

Collection::insert($cardQueryList);

Приведенный выше код создает новые строки, даже если строка существует. Как я могу сделать так, что если строка существует, она обновляется. А если это не так, это создает ряд? Ответ Eloquent или Fluent был бы оптимальным, но я открыт, если нет другого пути.

Я хотел бы сделать массовое обновление / вставку с помощью одного запроса. Не для цикла запросов для каждой записи. В идеале я хотел бы попасть в базу данных один раз по понятным причинам.

Также я уже проверил следующую ссылку:

Вставьте новую запись, если она не существует, и обновите, если существует, laravel eloquent

Вышеуказанное работает для одной записи обновления / вставки. Что, если я бегу с циклом for, будет очень медленным. Я ищу ответ, который позволяет массовую вставку / обновление в одном запросе.

Примечание: в качестве ключа я использую и username, и card_uid. Таким образом, в основном, когда я нахожу строку с указанным именем пользователя и card_uid, я хотел бы обновить соответствующую строку. В противном случае создайте новую строку.

4 ответа

Как правило, тип sql, который вы используете, будет примерно таким:

    insert into `TABLE` ( `FIELD1`,`FIELD2`, `FIELD3` ) values ( 'VALUE1','VALUE2','VALUE3' )
    on duplicate key
        update
            `FIELD1`='VALUE1',
            `FIELD2`='VALUE2',
            `FIELD1`='VALUE3';

Как бы вы использовали это с Laravel, я не могу вам сказать! Упс - забыли имена полей в обновлении

<?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 не пуст.

Если вы не хотите, чтобы дубликаты содержали схему БД, не допускайте ввода дубликатов. Поймай ошибку в этом случае и просто продолжай.

Вы можете попробовать это:

Collection::firstOrNew([
    'username' => $user->username,
    'card_uid' => $card->uid,
    'have_quantity' => $cards['quantity']
])
->save();

Чтобы это работало, добавьте $fillable свойство с массовыми назначаемыми именами полей в вашем Collection модель, например:

protected $fillable = ['username', 'card_uid', 'have_quantity'];
Другие вопросы по тегам