【问题标题】:inserting multiple values in mysql table using PDO使用 PDO 在 mysql 表中插入多个值
【发布时间】:2017-01-23 16:29:36
【问题描述】:

我有一个将复选框提交给 PHP PDO 脚本的表单。我有如下代码将值存储到 mysql 表中

$stmt = $dbPDO->prepare("INSERT INTO group_members(g_id, em_id) 
                         VALUES(:g_id,:em_id) 
                         ON DUPLICATE KEY UPDATE g_id = :g_id,  em_id = :em_id");
foreach ($_POST['id'] as $email) {
  $stmt->bindParam(':g_id', $gid , PDO::PARAM_INT);
  $stmt->bindParam(':em_id', $email , PDO::PARAM_STR);
  $stmt->execute();
}

PHP 致命错误:未捕获的异常 'PDOException' 带有消息 'SQLSTATE[HY093]: Invalid parameter number'

这会产生错误。将多个值插入具有不同值的 mysql 表中的最佳方法是什么?

【问题讨论】:

  • 最好的方法是阅读手册You must include a unique parameter marker for each value you wish to pass in to the statement when you call PDOStatement::execute(). You cannot use a named parameter marker of the same name more than once in a prepared statement, unless emulation mode is on.

标签: php mysql pdo


【解决方案1】:

每个命名占位符都必须是唯一的!

$stmt = $dbPDO->prepare("INSERT INTO group_members(g_id, em_id) VALUES(:g_id,:em_id) ON DUPLICATE KEY UPDATE g_id = :g_id2,  em_id = :em_id2");

$email=null;
//just bind once, that the logic behind 'bind()'
$stmt->bindParam(':g_id', $gid , PDO::PARAM_INT);
$stmt->bindParam(':em_id', $email , PDO::PARAM_STR);
$stmt->bindParam(':g_id2', $gid , PDO::PARAM_INT);
$stmt->bindParam(':em_id2', $email , PDO::PARAM_STR);

foreach ($_POST['id'] as $email) {
    $stmt->execute();//write your rows
}
$stmt->close();

【讨论】:

  • //just bind once, that the logic behind 'bind()' 是这个问题的关键。希望这可以帮助某人。那里没有让我做出这个评估的好信息。虽然@颜值现在看起来很明显。该语句使用循环设置的绑定参数的当前值执行。因此,循环设置的 $email 的当前值是语句使用的 without explict definition of the bind parameteres inside the loop. Ofcource 值不能在没有 emulation mode on 的情况下被重用。
【解决方案2】:

您不能重复使用占位符名称。您必须创建新的,或在更新部分使用 VALUES:

$stmt = $dbPDO->prepare("INSERT INTO group_members(g_id, em_id) VALUES(:g_id,:em_id) ON DUPLICATE KEY UPDATE g_id = VALUES(g_id),  em_id = VALUES(em_id)");

【讨论】:

  • 这基本上是正确的。如果你开启了仿真模式,那么你可以重复使用占位符
【解决方案3】:

除非您打开了emulation mode,否则您不能重复使用占位符。

一般来说,PDO_MYSQL 应该默认开启仿真。原因是 MySQL 在准备好的语句方面表现不佳。仿真的工作速度明显更快。

也就是说,如果由于某种原因没有打开,您可以使用手动设置:

$dbc->setAttribute(PDO::ATTR_EMULATE_PREPARES,true);

其实,如果你不确定,随便设置就行了。

【讨论】:

  • 在 u_mulder 的评论中注明。
  • @JustOnUnderMillions - cmets 将被视为短暂的,所以我将其作为答案。
  • 我想我可以找人告诉你,你的回答可以是评论。 ;) 快速评论。但是,如果 emulation mode 关闭 ,一个好的答案也会告诉你该怎么做 :) 但是神经。 OB似乎根本没有回复。 ;)
  • @JustOnUnderMillions - 放松一下。我在做这个工作。快速的答案就是让 OP 认为他不是其他答案中的 SOL。看来我不必担心,但仍然如此。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-12
  • 1970-01-01
  • 2013-06-13
  • 1970-01-01
相关资源
最近更新 更多