2015-04-11 10 views
7

Mi chiedo come si va a fare un database di massa INSERT in Yii2?Come inserire un database di massa in Yii2?

Ad esempio, un normale INSERT vorrei così:

$sql = $this->db("INSERT INTO some_table(id,my_value) VALUES(:id,:my_value)"); 
$sql->bindValues([':id' => $id, ':my_value' => $my_value]); 
$sql->execute(); 

Ora, cosa succede se ho voluto creare una massa INSERT?

Senza valori vincolante si potrebbe qualcosa di simile:

foreach ($foo as $bar) { 
    $data_sql .= '(' . $id . ',' "'" . $bar . "')," 
} 

$data_sql = rtrim($data_sql, ','); 

$sql = $this->db("INSERT INTO some_table(id,my_value) VALUES" . $data_sql); 
$sql->execute(); 

Ma come è possibile raggiungere questo obiettivo se si vuole ancora di legare i valori?

Modifica: Questa domanda non è la stessa di quella collegata poiché non sto utilizzando ActiveRecord.

Edit 2:

Idealmente sarebbe bello se ci fosse una soluzione che offrisse una certa flessibilità, come l'essere in grado di scrivere la maggior parte della propria sintassi, come una delle risposte postate di seguito:

Yii::$app->db->createCommand()->batchInsert('tableName', ['id', 'title', 'created_at'], [ 
    [1, 'title1', '2015-04-10'], 
    [2, 'title2', '2015-04-11'], 
    [3, 'title3', '2015-04-12'], 
])->execute(); 

... non offre questo. Per questa particolare situazione ho bisogno di usare l'istruzione IGNORE, che la soluzione di cui sopra non offre.

+0

creare qualcosa di simile 'INSERT INTO some_table (id, my_value) VALORI, (? ?,),, (?,?) 'e riempiono i segnaposto? –

+0

Beh, avevo pensato di fare qualcosa di simile aggiungendo numeri alla fine di ogni segnaposto, ma speravo che ci fosse un modo migliore. – Brett

+0

possibile duplicato di [Inserimento batch ActiveRecord (yii2)] (http://stackoverflow.com/questions/27355262/activerecord-batch-insert-yii2) – arogachev

risposta

22

C'è un metodo batchInsert speciale per questo: (?,?) (? ?,)

Yii::$app->db->createCommand()->batchInsert('tableName', ['id', 'title', 'created_at'], [ 
    [1, 'title1', '2015-04-10'], 
    [2, 'title2', '2015-04-11'], 
    [3, 'title3', '2015-04-12'], 
])->execute(); 
+0

Presumo che ciò non comporterà alcuna convalida – tinybyte

+0

Presumo che questo abbia la stessa sicurezza come quando si legano valori in cui non è necessario disinfettare i dati prima di trasmetterli? Inoltre, lo sfortunato problema con questo è che non è molto flessibile, ad esempio se si desidera utilizzare altre cose nella query come "INSERTO IGNORA". – Brett

+0

Questo metodo è sicuro poiché utilizza metodi speciali per la quotazione dei valori. E se hai bisogno, puoi estrarre la query sql finale e cambiarla. –