web-dev-qa-db-ja.com

/ PHPおよびPDOを使用して単一のMySQLプリペアドステートメントに配列を挿入する方法

オンライン登録中に、顧客は登録することを選択したいくつかのプログラムを選択できます。これらのプログラムは3桁の整数であり、配列に格納されます。

例えば:

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の場合、特にプレースホルダー(?)の場合、これがどのように機能するのかよくわかりません。

助言がありますか?

16
JM4

プログラムでクエリを作成できます...:

$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);
}
29
ircmaxell

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);
9
Xavier Barbosa

あなたが探しているのは、BULK挿入を行う方法です。これは、PDO自体よりもSQLに関連しています。

* _queryを使用する場合とまったく同じことを実行し、一括挿入クエリとparam配列を並べて作成するだけです。

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

これは醜いですが、機能するアルゴリズムだと思います。

0
Pierre