Как вставить массив в один оператор MySQL Prepared с PHP и PDO - PullRequest
15 голосов
/ 07 января 2011

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

Например:

Я хочу зарегистрироваться в программах с номерами программ 155, 165, 175 и 185.

MyМассив настроен так просто:

$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 я не совсем уверен, как это работает, особенно с заполнителями (?).

Есть предложения?

Ответы [ 3 ]

27 голосов
/ 07 января 2011

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

$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);
}
9 голосов
/ 07 января 2011

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);
0 голосов
/ 07 января 2011

То, что вам нужно, это как сделать 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);

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...