これを行うために生のSQLを書き込まずに、ケーキに複数の行の挿入を1つのクエリで実行させる方法はありますか? saveManyおよびsaveAssociatedオプションは、単一のトランザクション内に複数の行を保存するだけですが、そのトランザクションには複数の挿入文が含まれているため、重いアプリケーションを記述するための解決策ではありません。1つのクエリで複数の行を保存する
読んでいただきありがとうございます。
これを行うために生のSQLを書き込まずに、ケーキに複数の行の挿入を1つのクエリで実行させる方法はありますか? saveManyおよびsaveAssociatedオプションは、単一のトランザクション内に複数の行を保存するだけですが、そのトランザクションには複数の挿入文が含まれているため、重いアプリケーションを記述するための解決策ではありません。1つのクエリで複数の行を保存する
読んでいただきありがとうございます。
はいあなたは
の下のように使用することができますgetDataSource()
方法は、CakePHP 2.xで静的なので、あなたが使用することができるはず:
$db = ConnectionManager::getDataSource('default');
$db->rawQuery($some_sql);
ここで私が行うための方法を掲示しています。複数の行を一度に挿入するには、手動でSQL
文を作成する必要があります。
もっとお手伝いできるかどうか教えてください。
-1これを行うための未処理のSQLを書き込まないでください。 – AD7six
従来のSQLでこれを行うと、私は自分のフレームワーク内にとどまりたいです。生のSQLは最後の手段です。私はこれを見つけました:https://github.com/jmillerdesign/CakePHP_Big_Data – systematical
それはアプリランドコードでそうするのが一般的ではありませんし、そうすることは、ほぼすべてのアプリケーションロジック(検証ルール、行動、イベントなど)を使用する可能性を削除しますけれども。マルチのインサートを使用して - あなたはまた、アプリのデータベースにフィクスチャファイルをロードする(直接またはあなたのコードの基礎として)this repository便利を見つけることが
$db = ConnectionManager::getDataSource('default');
$table = "stuffs";
$fields = array('id', 'name');
$values = array(
array(1, 'one'),
array(2, 'two'),
...
);
$result = $db->insertMulti($table, $fields, $values);
:あなたは道fixtures are loadedでこれを行うの一例を見ることができます。
これは、一度に1つのトランザクションを1つの行にまとめて挿入しているようです... – systematical
ハ! [それを気付かなかった](https://github.com/cakephp/cakephp/blob/master/lib/Cake/Model/Datasource/DboSource.php#L2917)。ビッグデータビヘイビアレスポンスのコメントに記載されているように、これを行うために十分頻繁に行う場合は、選択したソリューションが適切な値をエスケープしていることを確認してください。 – AD7six
はい、Big_Dataバルクを挿入するための良いアイデアである方に私を指摘しました。しかし、AD7sixノートでは、引き続き基本的な値の引用が使用され、挿入IDは返されません。あなたのアイデアに基づいて、私は、デフォルトのCakePHPクォートと挿入されたレコードのIDを使用して、単一のクエリに大量のデータを挿入する小さなスクリプトを書いていました。
$count = count($records);
$dbSource = $this->getDataSource();
$table = $dbSource->fullTableName($this->table);
$fields = $dbSource->prepareFields($this, array('fields' => array_keys($records[0])));
$values = array();
foreach ($records as $index => $record) {
if (!is_array($record) || !$record) {
return null;
}
foreach ($record as $column => $value) {
$values[$index][$column] = $dbSource->value($value, $this->getColumnType($column));
}
$values[$index] = '(' . implode(',', $values[$index]) . ')';
}
$query = 'INSERT INTO %s (%s) VALUES %s;';
$query = sprintf($query, $table, implode(',', $fields), implode(',', $values));
if (!$dbSource->execute($query)) {
return false;
}
$lastInsertId = $dbSource->getConnection()->lastInsertId();
$insertIds = array();
for ($i = 0; $i < $count; $i++) {
$insertIds[] = $lastInsertId + $i;
}
return $insertIds;
あなたはCakePHPの3.0を使用している場合は、この質問への答えを確認することができます:あなたはCakePHPの2を使用している場合How to use insert in query builder insert multiple records?
あなたは、このように生のSQLを使用する必要があります:
$sql = "INSERT INTO `people` (`name`,`title`) VALUES ";
foreach($people as $person){
list($name,$title) = $person;
$sql.= "('$name','$title'),";
}
$this->query(substr($sql,0,-1));
注意=)。その動作は、(おそらく)便利なAPIを持っていますが、生のSQLを書いています。データが単純でない場合は、SQL構文エラーが発生します。これは基本的な[値の引用](https://github.com/jmillerdesign/CakePHP_Big_Data/blob/master/Model/Behavior/BigDataBehavior.php# L146)。また、完全な行の挿入/更新以外は何もしないように見えます。とにかくそれを使用したいのであれば、単に[insertMulti](https://github.com/cakephp/cakephp/blob/master/lib/Cake/Model/Datasource/DboSource.php#L2894)を呼び出すように更新することをお勧めします。エスケープされていないraw SQLクエリは、発生するのを待っている問題です。 – AD7six
コメントありがとうございます。 – systematical