Как вставить массив в одно заявление MySQL Prepared с PHP и PDO

Во время онлайн-регистрации клиент может выбрать ряд программ, на которые они хотят зарегистрироваться. Эти программы представляют собой трехзначные целые числа и хранятся в массиве.

Например:

Я хочу записаться в programid 155, 165, 175 и 185.

Мой массив настроен так же просто, как:

$data = array(); $data[] = 155; $data[] = 165; $data[] = 175; $data[] = 185; 

Когда придет время вставить эту информацию в связанную таблицу, я также включаю дополнительные элементы из другой части регистрации:

Например, если бы я делал заявление о вставке программы SINGLE, он выглядел бы следующим образом:

 $stmt = $db->prepare("INSERT INTO table SET memberID=?, programID=?, date_added=NOW()"); $stmt->execute(array($memberid, 155)); 

Обычно я создавал бы простой цикл для массива выше, который вызывал бы несколько экземпляров оператора sql и выполнял бы такие как:

 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])); } 

Я понимаю, что приведенный выше код недействителен ($ data [$ j]), но ищет правильный способ совершения вызова.

Мне также сказали, что построение одного динамического оператора sql в целом лучше, чем несколько вызовов, как описано выше. Мой первый проход будет примерно таким:

 $sql = array(); foreach( $data as $row ) { $sql[] = '("'.$memberid.'", "'.$row[$j].'", NOW()")'; } mysql_real_query('INSERT INTO table (memberid, programid) VALUES '.implode(',', $sql)); 

но с PDO я не совсем уверен, как это работает, особенно с заполнителями (?).

Какие-либо предложения?

Вы можете запрограммировать запрос …:

 $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 решения

 // 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)); } 

А также

 // 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); 

То, что вы ищете, – это как сделать BULK-вставку, это больше связано с SQL, чем с самим PDO.

Вам нужно только сделать то же самое, что и с * _query, построить свой массивный запрос вставки и ваш массив параметров рядом.

 $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); 

Думаю, это уродливый, но рабочий алгоритм.