问题
Using PDO in PHP, when having to insert multiple rows into a table at once, I've used sql that looks something like this:
INSERT INTO some_names (firstName, lastName) VALUES ('Joe', 'Smith'),('Fred','Sampson'),('Lisa','Pearce');
As you can see I'm inserting three rows with one statement. The reason I do this is that I believe it is more efficient than executing three distinct statements to insert the rows.
So my question is this: how do I do this in PHP if I want to be able to bind my values to a statement like I do in single statement:
$query= ("INSERT INTO table (firstName, lastName) VALUE (:firstName, :lastName)", array = (
"firstname"=>$firstName,
"lastName"=>$lastName));
So my question is: Is there any way to bind in a multi-insert statement? Something like:
INSERT INTO table (firstName, lastName) VALUES((:firstName, :lastName),(:firstName, :lastName));
回答1:
Just create your query text wtih ?
placeholders as:
INSERT INTO table (firstName, lastName) VALUES (?, ?),(?, ?),(?, ?)
And execute it. Sample code can be:
$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);
回答2:
In theory, it might sound like a single statement is more efficient because you avoid making multiple calls to MySQL server, but the reality is that this a micro-optimization and you are overcomplicating your code for barely any benefit.
The cool thing about prepared statements is that it is prepared once and can be executed multiple times. This already saves you parsing the SQL statement multiple times. Simply prepare a statement outside of a loop and then execute it inside a loop.
$names = [['Joe', 'Smith'], ['Fred', 'Sampson'], ['Lisa', 'Pearce']];
$stmt = $pdo->prepare('INSERT INTO table (firstName, lastName) VALUES(?,?)');
foreach ($names as $name) {
$stmt->execute($name);
}
If you wrap the whole thing in a transaction as Your Common Sense suggested in the comments then there is no noticeable difference in performance compared to one big statement.
$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();
来源:https://stackoverflow.com/questions/62105003/pdo-and-binding-multiple-value-sets-during-insert-recently