【问题标题】:How to insert an array into a single MySQL Prepared statement w/ PHP and PDO如何使用 PHP 和 PDO 将数组插入到单个 MySQL Prepared 语句中
【发布时间】:2011-06-05 11:13:40
【问题描述】:

在在线注册期间,客户可以选择他们选择注册的多个计划。这些程序是三位整数,并存储在一个数组中。

例如:

我想注册 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,我不太确定它是如何工作的,尤其是对于占位符 (?)。

有什么建议吗?

【问题讨论】:

  • 不要多次运行准备。它已准备好,您可以使用不同的值多次执行它。

标签: php mysql loops pdo


【解决方案1】:

您可以以编程方式构建查询...:

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

【讨论】:

  • 感谢您的建议。我现在正在玩弄它。内爆抛出一个错误,但我会让你知道发生了什么。
  • 太棒了。谢谢您的帮助!通过上面示例中的 date_added 进行思考,创建一个新的 $insertdata[] = NOW() 元素将无法正确插入(因为 PDO 会将其视为 varchar 输入并按字面意思处理而不是 mysql 日期格式。通常我会简单地生成查询: date_add = NOW() 但使用上述值,可以这样做吗?我确实意识到我可以简单地运行 php date(Ymd H:i:s) 但想看看 NOW() 是否可行。跨度>
  • 你做的这么简单 +1。尊重
【解决方案2】:

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

【讨论】:

  • 感谢您的帖子,但是,上面的第一个答案不是比后者更多地查询和对数据库征税吗? (大多数人告诉我不要这样使用)。我将测试后者,因为它似乎更适合我的需求。注意:我在执行多个查询时零问题,只是被告知它“较慢”(最多 8 条记录,一秒钟对我来说毫无意义)。
  • 多个查询慢了大约十毫秒,但它们更具可读性和更容易调试。
【解决方案3】:

您正在寻找的是如何进行 BULK 插入,这比 PDO 本身更与 SQL 相关。

您只需执行与 *_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);

我认为这是一个丑陋但有效的算法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-27
    • 2013-05-19
    • 2017-02-10
    • 2012-04-09
    • 2014-10-23
    相关资源
    最近更新 更多