Mysql
 sql >> Base de données >  >> RDS >> Mysql

Insérer plusieurs lignes avec des instructions préparées PDO

La première chose importante à dire est que vous pouvez insérer plusieurs lignes grâce à une seule INSERT requête

INSERT INTO Table (col1, col2, col3) 
VALUES ('abc', 'def', 'ghi'),
       ('abc', 'def', 'ghi'),
       ('abc', 'def', 'ghi'),
       ('abc', 'def', 'ghi'),
       ('abc', 'def', 'ghi')
       -- and so on...

Une fois que vous savez cela, vous pouvez obtenir une bonne solution avec PDO (par exemple).
Vous devez garder à l'esprit que vous voulez une prepare complète et execute processus (en termes de sécurité, vous devez passer chaque paramètre séparément).

Supposons que vous ayez des lignes à insérer structurées comme suit :

$rows = array(
              array('abc', 'def', 'ghi'), // row 1 to insert
              array('abc', 'def', 'ghi'), // row 2 to insert
              array('abc', 'def', 'ghi')  // row 3 to insert
              // and so on ...
);

Votre objectif est d'avoir ce résultat sous la forme d'une requête préparée :

INSERT INTO Table (col1, col2, col3) 
VALUES (?, ?, ?),
       (?, ?, ?),
       (?, ?, ?)

Avec son exécution correspondant :

PDOStatement::execute(array('abc', 'def', 'ghi', 'abc', 'def', 'ghi', 'abc', 'def', 'ghi'));


Eh bien, vous seulement faut le faire maintenant :

$rows = array(
              array('abc', 'def', 'ghi'),
              array('abc', 'def', 'ghi'),
              array('abc', 'def', 'ghi')
);

$row_length = count($rows[0]);
$nb_rows = count($rows);
$length = $nb_rows * $row_length;

/* Fill in chunks with '?' and separate them by group of $row_length */
$args = implode(',', array_map(
                                function($el) { return '('.implode(',', $el).')'; },
                                array_chunk(array_fill(0, $length, '?'), $row_length)
                            ));

$params = array();
foreach($rows as $row)
{
   foreach($row as $value)
   {
      $params[] = $value;
   }
}

$query = "INSERT INTO Table (col1, col2, col3) VALUES ".$args;
$stmt = DB::getInstance()->prepare($query);
$stmt->execute($params);

Et... c'est tout !

De cette façon, chaque paramètre est traité séparément, c'est ce que vous voulez (sécurité, sécurité, sécurité !) et le tout, de manière dynamique, avec un seul INSERT requête

Si vous avez trop de lignes à insérer (voir ceci ), vous devez execute un par un

$rows = array(
              array('abc', 'def', 'ghi'), // row 1 to insert
              array('abc', 'def', 'ghi'), // row 2 to insert
              array('abc', 'def', 'ghi')  // row 3 to insert
              // and so on ...
);

$args = array_fill(0, count($rows[0]), '?');

$query = "INSERT INTO Table (col1, col2, col3) VALUES (".implode(',', $args).")";
$stmt = $pdo->prepare($query);

foreach ($rows as $row) 
{
   $stmt->execute($row);
}