2014-10-26 4 views
0

Я использую CakePHP 3 и MySQL.Как реализовать INSERT ON DUPLICATE KEY UPDATE aka upsert в CakePHP 3?

Я хотел бы ввести INSERT on DUPLICATE KEY UPDATE aka upsert запрос через CakePHP 3 модель.

Учитывая следующую таблицу:

+----+----------+-----+ 
| id | username | age | 
+----+----------+-----+ 
| 1 | admin | 33 | 
| 2 | Timmy | 17 | 
| 3 | Sally | 23 | 
+----+----------+-----+ 

где id является первичным ключом и username является уникальным индексом

Когда у меня есть следующие значения в ожидании быть upserted:

Felicia, 27 
Timmy, 71 

Я ожидаю следующий результат: после upsert:

+----+----------+-----+ 
| id | username | age | 
+----+----------+-----+ 
| 1 | admin | 33 | 
| 2 | Timmy | 71 | 
| 3 | Sally | 23 | 
| 4 | Felicia | 27 | 
+----+----------+-----+ 

Я знаю, как сделать upsert в запросе MySQL:

INSERT INTO `users` (`username`, `age`) 
VALUES ('Felicia', 27), ('Timmy', 71) 
ON DUPLICATE KEY UPDATE 
`username`=VALUES(`username`),`age`=VALUES(`age`); 

Я знаю, как сделать это в более чем один запрос в CakePHP3.

$newUsers = [ 
     [ 
      'username' => 'Felicia', 
      'age' => 27, 
     ], 
     [ 
      'username' => 'Timmy', 
      'age' => 71, 
     ], 
    ]; 

    foreach ($newUsers as $newUser) { 
     $existingRecord = $this->Users->find() 
      ->select(['id']) 
      ->where(['username' => $newUser['username']]) 
      ->first(); 

     if (empty($existingRecord)) { 
      $insertQuery = $this->Users->query(); 
      $insertQuery->insert(array_keys($newUser)) 
       ->values($newUser) 
       ->execute(); 
     } else { 
      $updateQuery = $this->Users->query(); 
      $updateQuery->update() 
       ->set($newUser) 
       ->where(['id' => $existingRecord->id]) 
       ->execute(); 
     } 
    } 

То, что я хочу знать:

есть способ сделать upsert с помощью CakePHP 3 в одной строке, даже если я использую цепочки?

Просьба сообщить, как это реализовать.

+0

StackOverflow не является службой записи кода. Пожалуйста, напишите, что вы пробовали на сегодняшний день и какая у вас проблема. –

+2

Возможный дубликат [CakePHP 3.0: как сделать вставку при повторном обновлении ключа?] (Http://stackoverflow.com/questions/24852904/cakephp-3-0-how-to-do-an-insert-on- не дублировать ключ-обновление) – ndm

+0

просто очистить: подмигнули нет дубликата [CakePHP 3.0: Как сделать вставку на дубликат ключа обновления?] [1] [1]: HTTP: // StackOverflow ,com/questions/24852904/cakephp-3-0-how-to-do-a-insert-on-duplicate-key-update – Dirk

ответ

3

Используя ответ, указанный в https://stackoverflow.com/a/24990944/80353, я хочу перефразировать это, используя образец кода, заданный в вопросе.

Для запуска upsert на следующих записях

Felicia, 27 
Timmy, 71 

в эту таблицу

+----+----------+-----+ 
| id | username | age | 
+----+----------+-----+ 
| 1 | admin | 33 | 
| 2 | Timmy | 17 | 
| 3 | Sally | 23 | 
+----+----------+-----+ 

лучший способ это написать как

$newUsers = [ 
    [ 
     'username' => 'Felicia', 
     'age' => 27, 
    ], 
    [ 
     'username' => 'Timmy', 
     'age' => 71, 
    ], 
]; 

$columns = array_keys($newUsers[0]); 

$upsertQuery = $this->Users->query(); 

$upsertQuery->insert($columns); 

// need to run clause('values') AFTER insert() 
$upsertQuery->clause('values')->values($newUsers); 

$upsertQuery->epilog('ON DUPLICATE KEY UPDATE `username`=VALUES(`username`), `age`=VALUES(`age`)') 
       ->execute(); 

Проверьте this за подробную информацию о epilog

Проверить this Подробнее о том, как написать вставку нескольких записей в одном запросе