一次查询 MySQL 插入多行
Posted
技术标签:
【中文标题】一次查询 MySQL 插入多行【英文标题】:Insert multiple rows with one query MySQL 【发布时间】:2012-09-12 04:39:31 【问题描述】:我想编写脚本,具有多个插入查询的功能。 让我更好地解释一下。
我有一个quantity
以html 形式输入。
我有 mysql 查询将registered user
插入表中。
所以我希望我的函数为“数量”时间插入此查询。
mysql_query("INSERT INTO `pxlot` (realname,email,address,phone,status,regtime,ip)
VALUES ('$realname','$email','$address','$phone','0','$dateTime','$ip')")
or die (mysql_error()); // Inserts the user.
例如插入 3 次。 有什么建议?
【问题讨论】:
如果您在给定表中多次重复同一行相同的值,那么您做错了。您需要返回并重新评估您的架构设计。 顺便说一句 mysql_* 已被弃用 【参考方案1】: INSERT INTO table (a,b) VALUES (1,2), (2,3), (3,4);
http://dev.mysql.com/doc/refman/5.5/en/insert.html
【讨论】:
语句中列值列表的限制是什么?我的意思是我们可以将多少个元组(1,2)
传递到单个 INSERT
语句中。
@akshay,我真的不知道答案,我怀疑限制不在于元组的数量,而在于由max_allowed_packet
mysql 系统变量控制的语句大小。我认为默认值是 1MB,协议最大 1GB。【参考方案2】:
在大多数情况下,在 MySQL 中使用一条 Insert 语句插入多条记录比在 php 中使用 for/foreach 循环插入记录要快得多。
假设 $column1 和 $column2 是 html 表单发布的大小相同的数组。
您可以像这样创建查询:
<?php
$query = 'INSERT INTO TABLE (`column1`, `column2`) VALUES ';
$query_parts = array();
for($x=0; $x<count($column1); $x++)
$query_parts[] = "('" . $column1[$x] . "', '" . $column2[$x] . "')";
echo $query .= implode(',', $query_parts);
?>
如果为两条记录发布数据,查询将变为:
插入表(
column1
,column2
)值('data','data'),('data','data')
【讨论】:
【参考方案3】:这里有一些方法可以做到这一点
INSERT INTO pxlot (realname,email,address,phone,status,regtime,ip)
select '$realname','$email','$address','$phone','0','$dateTime','$ip'
from SOMETABLEWITHTONSOFROWS LIMIT 3;
或
INSERT INTO pxlot (realname,email,address,phone,status,regtime,ip)
select '$realname','$email','$address','$phone','0','$dateTime','$ip'
union all select '$realname','$email','$address','$phone','0','$dateTime','$ip'
union all select '$realname','$email','$address','$phone','0','$dateTime','$ip'
或
INSERT INTO pxlot (realname,email,address,phone,status,regtime,ip)
values ('$realname','$email','$address','$phone','0','$dateTime','$ip')
,('$realname','$email','$address','$phone','0','$dateTime','$ip')
,('$realname','$email','$address','$phone','0','$dateTime','$ip')
【讨论】:
【参考方案4】:虽然使用单个 INSERT
语句插入多行通常更快,但它会导致更复杂且通常不安全的代码。下面我将介绍使用 PHP 一次性插入多条记录的最佳实践。
要同时向数据库中插入多条新行,需要遵循以下 3 个步骤:
-
启动事务(禁用自动提交模式)
准备
INSERT
声明
多次执行
使用数据库事务可确保数据保存在一块并显着提高性能。
如何使用 PDO 正确插入多行
PDO 是 PHP 中最常见的数据库扩展选择,使用 PDO 插入多条记录非常简单。
$pdo = new \PDO("mysql:host=localhost;dbname=test;charset=utf8mb4", 'user', 'password', [
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
\PDO::ATTR_EMULATE_PREPARES => false
]);
// Start transaction
$pdo->beginTransaction();
// Prepare statement
$stmt = $pdo->prepare('INSERT
INTO `pxlot` (realname,email,address,phone,status,regtime,ip)
VALUES (?,?,?,?,?,?,?)');
// Perform execute() inside a loop
// Sample data coming from a fictitious data set, but the data can come from anywhere
foreach ($dataSet as $data)
// All seven parameters are passed into the execute() in a form of an array
$stmt->execute([$data['name'], $data['email'], $data['address'], getPhoneNo($data['name']), '0', $data['regtime'], $data['ip']]);
// Commit the data into the database
$pdo->commit();
如何使用mysqli正确插入多行
mysqli 扩展使用起来有点麻烦,但操作原理非常相似。函数名称不同,参数略有不同。
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new \mysqli('localhost', 'user', 'password', 'database');
$mysqli->set_charset('utf8mb4');
// Start transaction
$mysqli->begin_transaction();
// Prepare statement
$stmt = $mysqli->prepare('INSERT
INTO `pxlot` (realname,email,address,phone,status,regtime,ip)
VALUES (?,?,?,?,?,?,?)');
// Perform execute() inside a loop
// Sample data coming from a fictitious data set, but the data can come from anywhere
foreach ($dataSet as $data)
// mysqli doesn't accept bind in execute yet, so we have to bind the data first
// The first argument is a list of letters denoting types of parameters. It's best to use 's' for all unless you need a specific type
// bind_param doesn't accept an array so we need to unpack it first using '...'
$stmt->bind_param('sssssss', ...[$data['name'], $data['email'], $data['address'], getPhoneNo($data['name']), '0', $data['regtime'], $data['ip']]);
$stmt->execute();
// Commit the data into the database
$mysqli->commit();
性能
这两个扩展都提供了使用事务的能力。使用事务执行准备好的语句极大地提高了性能,但它仍然不如单个 SQL 查询。然而,差异是如此微不足道,以至于为了简洁和干净的代码,多次执行准备好的语句是完全可以接受的。如果您需要一个更快的选项来一次将多条记录插入数据库,那么 PHP 可能不是正确的工具。
【讨论】:
【参考方案5】:如果您想插入多个值,比如说从具有不同 post 值但要插入到同一个表中的多个输入中,那么只需使用:
mysql_query("INSERT INTO `table` (a,b,c,d,e,f,g) VALUES
('$a','$b','$c','$d','$e','$f','$g'),
('$a','$b','$c','$d','$e','$f','$g'),
('$a','$b','$c','$d','$e','$f','$g')")
or die (mysql_error()); // Inserts 3 times in 3 different rows
【讨论】:
以上是关于一次查询 MySQL 插入多行的主要内容,如果未能解决你的问题,请参考以下文章
MySQL ON DUPLICATE KEY UPDATE 在单个查询中插入多行