Lors d'une inscription en ligne, un client peut sélectionner un certain nombre de programmes pour lesquels il a choisi de s'inscrire. Ces programmes sont des entiers à trois chiffres et sont stockés dans un tableau.
Par exemple:
Je veux m'inscrire aux programmes 155, 165, 175 et 185.
Mon tableau est configuré aussi simplement que:
$data = array();
$data[] = 155;
$data[] = 165;
$data[] = 175;
$data[] = 185;
Lorsque vient le temps d'insérer ces informations dans la table associée, j'inclus également des éléments supplémentaires provenant de l'autre partie de l'inscription:
Par exemple, si je faisais une instruction d'insertion de programme SINGLE, cela ressemblerait à ceci:
$stmt = $db->prepare("INSERT INTO table SET memberID=?, programID=?, date_added=NOW()");
$stmt->execute(array($memberid, 155));
Je créerais normalement une boucle simple pour le tableau ci-dessus, qui appellerait plusieurs instances de l'instruction SQL et s'exécuterait, par exemple:
for($j = 0; $j < (count($data)-1); $j++) {
$stmt = $db->prepare("INSERT INTO table SET memberID=?, programID=?, date_added=NOW()");
$stmt->execute(array($memberid, $data[$j]));
}
Je me rends bien compte que le code ci-dessus est invalide ($ data [$ j]) mais je cherche la bonne façon de faire l'appel.
On m'a aussi déjà dit que la construction d'une seule déclaration SQL dynamique est globalement meilleure que plusieurs appels comme ci-dessus. Mon premier passage serait quelque chose comme:
$sql = array();
foreach( $data as $row ) {
$sql[] = '("'.$memberid.'", "'.$row[$j].'", NOW()")';
}
mysql_real_query('INSERT INTO table (memberid, programid) VALUES '.implode(',', $sql));
mais avec AOP, je ne sais pas trop comment cela fonctionne, en particulier avec des espaces réservés (?).
Aucune suggestion?
Vous pouvez créer la requête par programme ...:
$sql = 'INSERT INTO table (memberID, programID) VALUES ';
$insertQuery = array();
$insertData = array();
foreach ($data as $row) {
$insertQuery[] = '(?, ?)';
$insertData[] = $memberid;
$insertData[] = $row;
}
if (!empty($insertQuery)) {
$sql .= implode(', ', $insertQuery);
$stmt = $db->prepare($sql);
$stmt->execute($insertData);
}
2 solutions
// multiple queries
$stmt = $pdo->prepare('INSERT INTO table SET memberID=:memberID, programID=:programID, date_added=NOW()');
$data = array(155, 165, 175, 185);
foreach($data as $d) {
$stmt->execute(array(':memberID' => $memberid, ':programID' => $d));
}
Et
// one query
$data = array(155, 165, 175, 185);
$values = array();
foreach($data as $d) {
$values[] = sprintf('(%d, %d, NOW())', $d, $memberid);
}
$sql = sprintf('INSERT INTO table (memberID, programID, date_added) VALUES %s', implode (', ', $values));
$pdo->exec($sql);
Ce que vous cherchez, c'est comment faire une insertion BULK, c'est plus lié à SQL qu'à PDO lui-même.
Il vous suffit de faire exactement la même chose qu'avec * _query, de construire votre requête d'insertion en bloc et votre tableau de paramètres côte à côte.
$placeholder = array();
$values = "?, ?, ?, ...";
$args = array();
foreach ($arrays as $array) {
$placeholder[] = $value;
$args[] = $array['col1'];
$args[] = $array['col2'];
$args[] = $array['col3'];
...
}
$sql = "INSERT INTO table (col1, col2, ... ) VALUES ("
. implode('), (', $placeholder)
. ")";
$stmt = $db->prepare($sql);
$db->execute($sql, $args);
C'est un algorithme moche mais fonctionnel, je pense.