2017-01-28 3 views
1

Ich möchte batchinsert außer Kraft zu setzen, weil ich ON DUPLICATE KEY UPDATEyii2 batchinsert von Datenbank-Klasse außer Kraft setzen

$result = Yii::$app->db->createCommand()->batchInsert('product', ['asin', 'title', 'image', 'url', 'price'], $results)->execute(); 


public function batchInsert($table, $columns, $rows) 
{ 

    if (empty($rows)) { 
     return ''; 
    } 

    $schema = $this->db->getSchema(); 
    if (($tableSchema = $schema->getTableSchema($table)) !== null) { 
     $columnSchemas = $tableSchema->columns; 
    } else { 
     $columnSchemas = []; 
    } 

    $values = []; 
    foreach ($rows as $row) { 
     $vs = []; 
     foreach ($row as $i => $value) { 
      if (isset($columns[$i], $columnSchemas[$columns[$i]]) && !is_array($value)) { 
       $value = $columnSchemas[$columns[$i]]->dbTypecast($value); 
      } 
      if (is_string($value)) { 
       $value = $schema->quoteValue($value); 
      } elseif ($value === false) { 
       $value = 0; 
      } elseif ($value === null) { 
       $value = 'NULL'; 
      } 
      $vs[] = $value; 
     } 
     $values[] = '(' . implode(', ', $vs) . ')'; 
    } 

    $query = 'INSERT INTO ' . $schema->quoteTableName($table); 
    $duplicate = ' ON DUPLICATE KEY UPDATE '; 

    $last = end($columns); 
    reset($columns); 

    foreach ($columns as $i => $name) { 
     $columns[$i] = $schema->quoteColumnName($name); 
     $duplicate .= $schema->quoteColumnName($name) . ' = VALUES(' . $schema->quoteColumnName($name) . ')'; 

     if ($name <> $last) { 
      $duplicate .= ', '; 
     } 
    } 

    $query .= ' (' . implode(', ', $columns) . ') '; 
    $query .= ' VALUES ' . implode(', ', $values); 
    $query .= $duplicate; 

    return $query; 
} 

Dies funktioniert hinzufügen möchten aber jetzt brauche ich yii \ db \ Querybuilder Wenn diese gefunden außer Kraft zu setzen: Yii::$app->db->commandClass = new common\models\Command();

und ich kann die Befehlsklasse außer Kraft setzen, aber der Code in yii \ db \ Schema sollte auch

public function createQueryBuilder() 
{ 
    return new \common\models\QueryBuilder($this->db); 
} 

aktualisiert werden oder ich t brauchen o etwas völlig anderes machen, wie kann ich das beheben?

Antwort

1

Nach this discussion about non standard sql commands von Devs Sie tun können folgende (nicht getestet):

class MyQueryBuilder extends yii\db\mysql\QueryBuilder 
{ 
    public function batchInsert($table, $columns, $rows) 
    { 
     $sql = parent::batchInsert($table, $columns, $rows); 
     $sql .= 'ON DUPLICATE KEY UPDATE'; 
     return $sql; 
    } 
} 

oder Sie können dies tun:

$db = Yii::$app->db; 
$sql = $db->queryBuilder->batchInsert($table, $fields, $rows); 
$db->createCommand($sql . ' ON DUPLICATE KEY UPDATE')->execute(); 
+0

Dank, ON DUPLICATE KEY UPDATE funktioniert nicht für ich ohne asin = WERTE ( asin ), 'title' = WERTE (' title') etc, aber es funktioniert jetzt – Ruben

0
<?php 

namespace common\models; 

use yii\db\mysql\QueryBuilder as baseQueryBuilder; 

class QueryBuilder extends baseQueryBuilder 
{ 
    public function batchInsert($table, $columns, $rows) 
    { 
     $sql = parent::batchInsert($table, $columns, $rows); 
     $sql .= ' ON DUPLICATE KEY UPDATE '; 

     $schema = $this->db->getSchema(); 
     $last = end($columns); 
     reset($columns); 

     foreach ($columns as $i => $column) 
     { 
      $columns[$i] = $schema->quoteColumnName($column); 
      $sql .= $schema->quoteColumnName($column) . ' = VALUES(' . $schema->quoteColumnName($column) . ')'; 

      if ($column <> $last) { 
       $sql .= ', '; 
      } 
     } 

     return $sql; 
    } 
} 


$db = Yii::$app->db; 
$queryBuilder = new \common\models\QueryBuilder(Yii::$app->db); 
$query = $queryBuilder->batchInsert('product', ['asin', 'title', 'image', 'url', 'price'], $results); 
$db->createCommand($query)->execute(); 
Verwandte Themen