Browse Source

Merge pull request #1309 from nineinchnick/batch-insert

support for batch insert in sqlite older than 3.7.11
tags/2.0.0-beta
Qiang Xue 11 years ago
parent
commit
cf73f40d79
  1. 47
      framework/yii/db/sqlite/QueryBuilder.php
  2. 6
      tests/unit/framework/db/sqlite/SqliteQueryBuilderTest.php

47
framework/yii/db/sqlite/QueryBuilder.php

@ -42,6 +42,53 @@ class QueryBuilder extends \yii\db\QueryBuilder
]; ];
/** /**
* Generates a batch INSERT SQL statement.
* For example,
*
* ~~~
* $connection->createCommand()->batchInsert('tbl_user', ['name', 'age'], [
* ['Tom', 30],
* ['Jane', 20],
* ['Linda', 25],
* ])->execute();
* ~~~
*
* Note that the values in each row must match the corresponding column names.
*
* @param string $table the table that new rows will be inserted into.
* @param array $columns the column names
* @param array $rows the rows to be batch inserted into the table
* @return string the batch INSERT SQL statement
*/
public function batchInsert($table, $columns, $rows)
{
if (($tableSchema = $this->db->getTableSchema($table)) !== null) {
$columnSchemas = $tableSchema->columns;
} else {
$columnSchemas = [];
}
foreach ($columns as $i => $name) {
$columns[$i] = $this->db->quoteColumnName($name);
}
$values = [];
foreach ($rows as $row) {
$vs = [];
foreach ($row as $i => $value) {
if (!is_array($value) && isset($columnSchemas[$columns[$i]])) {
$value = $columnSchemas[$columns[$i]]->typecast($value);
}
$vs[] = is_string($value) ? $this->db->quoteValue($value) : $value;
}
$values[] = implode(', ', $vs);
}
return 'INSERT INTO ' . $this->db->quoteTableName($table)
. ' (' . implode(', ', $columns) . ') SELECT ' . implode(' UNION ALL ', $values);
}
/**
* Creates a SQL statement for resetting the sequence value of a table's primary key. * Creates a SQL statement for resetting the sequence value of a table's primary key.
* The sequence will be reset such that the primary key of the next new row inserted * The sequence will be reset such that the primary key of the next new row inserted
* will have the specified value or 1. * will have the specified value or 1.

6
tests/unit/framework/db/sqlite/SqliteQueryBuilderTest.php

@ -81,4 +81,10 @@ class SqliteQueryBuilderTest extends QueryBuilderTest
$this->setExpectedException('yii\base\NotSupportedException'); $this->setExpectedException('yii\base\NotSupportedException');
parent::testAddDropPrimaryKey(); parent::testAddDropPrimaryKey();
} }
public function testBatchInsert()
{
$sql = $this->getQueryBuilder()->batchInsert('{{tbl_customer}} t', ['t.id','t.name'], array(array(1,'a'), array(2,'b')));
$this->assertEquals("INSERT INTO {{tbl_customer}} t ('t'.\"id\", 't'.\"name\") SELECT 1, 'a' UNION ALL 2, 'b'", $sql);
}
} }

Loading…
Cancel
Save