Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CakePHP 3.0: How to do an insert on duplicate key update?

I have an array $articles like this

[
    (int) 0 => [
        'id' => '-@940039',
        'xe_dsca' => 'ÜP2768G/1',
        'xe_citg' => '1F0200',
        'xe_cuni' => 'stk',
        'xe_seak' => 'ÜP2768G/1',
        'xe_seab' => '',
        'xe_wght' => '0.0153',
        'xe_cwun' => 'kg',
        'xe_wgap' => '2',
        'xe_seri' => '2',
        'xe_ltct' => '2',
        'xe_qual' => '2',
        'xe_hama' => '2',
        'xe_ctyo' => 'DE',
        'xe_ccde' => '85045095',
        'xe_cpln' => '240000',
        'xe_spar' => '2',
        'xe_wear' => '2',
        'xe_ctyo_de' => null,
        'xe_cean' => null,
        'xe_ewm_dsce' => null,
        'xe_cood' => null,
        'xe_ewm_dsne' => null,
        'xe_ewm_dsge' => null,
        'xe_ewm_dsen' => null,
        'xe_ewm_dscz' => null,
        'xe_wgh1' => null,
        'xe_wgh2' => null,
        'xe_wgh3' => null
    ],
    (int) 1 => [
        'id' => '000-000500-00000',
        'xe_dsca' => 'DUMMY ZEITBUCHUNG',
        'xe_citg' => '1F0800',
        'xe_cuni' => 'stk',
        'xe_seak' => 'DUMMY ZEITBUCHUN',
        'xe_seab' => '000-000500-00000',
        'xe_wght' => '0',
        'xe_cwun' => 'kg',
        'xe_wgap' => '2',
        'xe_seri' => '2',
        'xe_ltct' => '2',
        'xe_qual' => '2',
        'xe_hama' => '2',
        'xe_ccde' => '000',
        'xe_cpln' => '930000',
        'xe_spar' => '2',
        'xe_wear' => '2',
        'xe_ctyo' => null,
        'xe_ctyo_de' => null,
        'xe_cean' => null,
        'xe_ewm_dsce' => null,
        'xe_cood' => null,
        'xe_ewm_dsne' => null,
        'xe_ewm_dsge' => null,
        'xe_ewm_dsen' => null,
        'xe_ewm_dscz' => null,
        'xe_wgh1' => null,
        'xe_wgh2' => null,
        'xe_wgh3' => null
    ]

In my Controller I have these lines

foreach ($articles AS $article) {
    $query = $this->Articles->query();
    $query
        ->insert($required_article_fields)
        ->values($article)
        ->execute();
}

This code works fine, but has anyone a suggestion for me how to do an insert on duplicate key update? And what is the best practice to save many rows of data at once?

like image 824
Dirk Avatar asked Jul 20 '14 17:07

Dirk


2 Answers

You can use the query epilog() method

foreach ($articles AS $article) {
  $query = $this->Articles->query();
  $query
    ->insert($required_article_fields)
    ->values($article)
    ->epilog('ON DUPLICATE KEY UPDATE field=field+1')
    ->execute();
}

you can also pass a QueryExpression object to the method if you need to safely pass values.

like image 85
José Lorenzo Rodríguez Avatar answered Oct 10 '22 11:10

José Lorenzo Rodríguez


As suggested by https://stackoverflow.com/a/26590483/80353

you can do

$query = $this->Articles->query();
$query->insert($required_article_fields);


// need to run clause('values') AFTER insert()
$valuesExpression = $query->clause('values')->values($articles);

$query->values($valuesExpression)
      ->epilog('ON DUPLICATE KEY UPDATE `field1`=VALUES(`field1`) ... ')
      ->execute();

I didn't fill in all the fields you want to update because I don't know which field is part of your unique index.

like image 36
Kim Stacks Avatar answered Oct 10 '22 11:10

Kim Stacks