2017-01-28 9 views
1

をbatchinsertを上書きyii2私はON DUPLICATE KEY UPDATEは、私がbatchinsertを上書きしたいデータベースクラスから

$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; 
} 

を追加したいので、これは機能していますが、この見つかった場合、今、私はYiiの\ DB \ QueryBuilder をオーバーライドする必要があります:​​

と私は、コマンドクラスをオーバーライドすることができますが、Yiiの\デシベルの\スキーマ内のコードは、あまりにも

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

を更新するか、私はトンを必要とします何かを完全に違うものにするにはどうしたらいいですか?

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; 
    } 
} 

か、この操作を行うことができます:

答えて

1

次の操作を行うことができます開発者のthis discussion about non standard sql commandsによると(テストしていません)

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

おかげで、DUPLICATE KEY UPDATE ONのために働いていません私はasin = VALUES( asin )、 'title' = VALUES(' title')などなしで、 – 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(); 
関連する問題