Laravel 5.1 Создайте или обновите дубликат
В Laravel 5.1, для вставки MySQL, я хочу посмотреть, существует ли запись уже и обновлять дубликаты или создавать новые, если они не существуют.
Я уже искал SO, где ответы были для старых версий laravel. В одной из старых тем сказано, что в прошлом году был добавлен новый метод updateOrCreate()
. Но когда я пытаюсь это сделать, я получаю сообщение об ошибке:
Integrity constraint violation: 1062 Duplicate entry '1' for key 'app_id'
Это запрос, который я использую:
AppInfo::updateOrCreate(array(
'app_id' => $postData['appId'],
'contact_email' => $postData['contactEmail']
));
Где app_id
- уникальный внешний ключ в этой таблице, и я хочу обновить запись, если она существует, или создать новую. Я пробовал искать документы 5.1 и не мог найти нужную мне информацию. Может ли кто-нибудь направить меня сюда, пожалуйста...
Ответы
Ответ 1
В соответствии с определением метода яркой модели "updateOrCreate()"
function updateOrCreate (атрибуты массива $, array $values = []) {}
требуется два аргумента...
- one - это атрибуты, которые вы хотите проверить в базе данных, если запись присутствует.
- second - это новые значения атрибутов, которые вы хотите создать или обновить.
AppInfo::updateOrCreate(['app_id' => $postData['appId']],
['contact_email' => $postData['contactEmail']]);
Ответ 2
Я создал пакет для работы с вставкой MySQL в дубликат ключа.
Это может быть полезно для других:
https://packagist.org/packages/yadakhov/insert-on-duplicate-key
Пример:
/**
* Class User.
*/
class User extends Model
{
use Yadakhov\InsertOnDuplicateKey;
...
}
// associative array must match column names
$users = [
['id' => 1, 'email' => '[email protected]', 'name' => 'User One'],
['id' => 2, 'email' => '[email protected]', 'name' => 'User Two'],
['id' => 3, 'email' => '[email protected]', 'name' => 'User Three'],
];
User::insertOnDuplicateKey($users);
Ответ 3
Добавьте следующий метод insertUpdate к вашей модели
<?php
namespace App;
use Illuminate\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Foundation\Auth\Access\Authorizable;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
class User extends Model implements AuthenticatableContract,
AuthorizableContract,
CanResetPasswordContract
{
use Authenticatable, Authorizable, CanResetPassword;
/**
* The database table used by the model.
*
* @var string
*/
protected $table = 'users';
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = ['name', 'email', 'password'];
/**
* The attributes excluded from the model JSON form.
*
* @var array
*/
protected $hidden = ['password', 'remember_token'];
public static function insertUpdate(array $attributes = [])
{
$model = new static($attributes);
$model->fill($attributes);
if ($model->usesTimestamps()) {
$model->updateTimestamps();
}
$attributes = $model->getAttributes();
$query = $model->newBaseQueryBuilder();
$processor = $query->getProcessor();
$grammar = $query->getGrammar();
$table = $grammar->wrapTable($model->getTable());
$keyName = $model->getKeyName();
$columns = $grammar->columnize(array_keys($attributes));
$insertValues = $grammar->parameterize($attributes);
$updateValues = [];
if ($model->primaryKey !== null) {
$updateValues[] = "{$grammar->wrap($keyName)} = LAST_INSERT_ID({$keyName})";
}
foreach ($attributes as $k => $v) {
$updateValues[] = sprintf("%s = '%s'", $grammar->wrap($k), $v);
}
$updateValues = join(',', $updateValues);
$sql = "insert into {$table} ({$columns}) values ({$insertValues}) on duplicate key update {$updateValues}";
$id = $processor->processInsertGetId($query, $sql, array_values($attributes));
$model->setAttribute($keyName, $id);
return $model;
}
}
Вы можете использовать:
App\User::insertUpdate([
'name' => 'Marco Pedraza',
'email' => '[email protected]'
]);
Следующий запрос будет выполнен:
insert into `users` (`name`, `email`, `updated_at`, `created_at`) values (?, ?, ?, ?) on duplicate key update `id` = LAST_INSERT_ID(id),`name` = 'Marco Pedraza',`email` = '[email protected]',`updated_at` = '2016-11-02 01:30:05',`created_at` = '2016-11-02 01:30:05'
Метод автоматически добавляет/удаляет метки времени "Красноречивый", если вы включили или отключили.
Ответ 4
Чтобы использовать функцию laravel updateOrCreate, вам нужна автоматическая инкремент id в вашей таблице.
то, что они делают,
select id from your_table where your_attributes
после этого получите идентификатор автоматического увеличения
затем
update your_table set your_values where field_id
Ответ 5
Я отвечаю на этот вопрос, потому что я не могу найти ответ, связанный с ON DUPLICATE KEY UPDATE, хотя я использую Laravel 5.4.
Если вы посмотрите на метод updateOrCreate в базовом коде Laravel, вы увидите, что после этого Laravel использует 2 разных запроса: один для обновления и другой для создания. Из-за этого иногда вы можете получать дублированные данные в БД. Поэтому в некоторых случаях может быть полезно написать такой необработанный запрос:
DB:: statement ( "INSERT INTO table_name
(col_1
, col_2
) VALUES (?,?) НА ОБНОВЛЕНИИ КОДА DUPLICATE col_1
= col_1
+ 1", ([val_1, val_2]));
Надеюсь, что это может быть полезно для кого-то.