【问题标题】:PDO and binding multiple value sets during insert - recentlyPDO 并在插入期间绑定多个值集 - 最近
【发布时间】:2020-05-30 15:55:17
【问题描述】:

在 PHP 中使用 PDO,当必须一次向表中插入多行时,我使用的 sql 看起来像这样:

INSERT INTO some_names (firstName, lastName) VALUES ('Joe', 'Smith'),('Fred','Sampson'),('Lisa','Pearce');

如您所见,我在一条语句中插入了三行。我这样做的原因是我相信它比执行三个不同的语句来插入行更有效。

所以我的问题是:如果我希望能够像在单个语句中那样将我的值绑定到语句中,我该如何在 PHP 中执行此操作:

$query= ("INSERT INTO table (firstName, lastName) VALUE (:firstName, :lastName)", array = (
    "firstname"=>$firstName,
    "lastName"=>$lastName));

所以我的问题是:有没有办法在多插入语句中绑定?比如:

INSERT INTO table (firstName, lastName) VALUES((:firstName, :lastName),(:firstName, :lastName));

【问题讨论】:

  • 只需绑定? 并传递您的所有数据。
  • “我相信它更有效” - 不,它不是
  • 你能想出一个更合适的标题吗?
  • @YourCommonSense 那么,向数据库发出多个请求与发出一个请求相同吗?
  • @Strawberry 这取决于你的想法。这个口头禅是一个很好的通用指南,但在上述情况下,性能改进可以忽略不计,并且会使代码变得不必要地复杂。您所说的主要适用于 N+1 问题或可以轻松避免额外调用的情况,而不会影响代码的可读性。多次调用会产生开销,但您应该问的问题是什么时候可以避免这种开销。

标签: php mysql sql pdo


【解决方案1】:

从理论上讲,由于您避免对 MySQL 服务器进行多次调用,因此听起来单个语句可能更有效,但现实情况是,这是一种微优化,您将代码过度复杂化,几乎没有任何好处。

prepared statements 很酷的一点是它可以准备一次并且可以执行多次。这已经节省了您多次解析 SQL 语句的时间。只需在循环外准备一条语句,然后在循环内执行即可。

$names = [['Joe', 'Smith'], ['Fred', 'Sampson'], ['Lisa', 'Pearce']];
$stmt = $pdo->prepare('INSERT INTO table (firstName, lastName) VALUES(?,?)');
foreach ($names as $name) {
    $stmt->execute($name);
}

如果您按照 cmets 中建议的常识将整个事物包装在事务中,那么与一个大语句相比,性能没有明显差异。

$names = [['Joe', 'Smith'], ['Fred', 'Sampson'], ['Lisa', 'Pearce']];
$stmt = $pdo->prepare('INSERT INTO people (firstName, lastName) VALUES(?,?)');
$pdo->beginTransaction();
foreach ($names as $name) {
    $stmt->execute($name);
}
$pdo->commit();

【讨论】:

【解决方案2】:

只需使用? 占位符将查询文本创建为:

INSERT INTO table (firstName, lastName) VALUES (?, ?),(?, ?),(?, ?)

并执行它。示例代码可以是:

$data = ['Joe', 'Smith','Fred','Sampson','Lisa','Pearce'];
$placeholders = ['(?, ?)', '(?, ?)', '(?, ?)'];  // but you should define this data according to your data
$query = 'INSERT INTO table (firstName, lastName) VALUES ' . implode(',', $placeholders);
$stmt = $dbh->prepare($query);
$stmt->execute($data);

【讨论】:

    猜你喜欢
    • 2013-03-12
    • 1970-01-01
    • 2012-09-02
    • 2014-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多