一次查询 MySQL 插入多行

Posted

技术标签:

【中文标题】一次查询 MySQL 插入多行【英文标题】:Insert multiple rows with one query MySQL 【发布时间】:2012-09-12 04:39:31 【问题描述】:

我想编写脚本,具有多个插入查询的功能。 让我更好地解释一下。

我有一个quantityhtml 形式输入。 我有 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);
?>

如果为两条记录发布数据,查询将变为:

插入表(column1column2)值('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中将单行插入查询重构为多行插入查询?

MySql - 使用连接子查询插入多行?

mysql 一次插入多行不同的数据

MySQL ON DUPLICATE KEY UPDATE 在单个查询中插入多行

求助~~ INSERT INTO....SELECT怎么一次性插入多行数据

Java:使用 PreparedStatement 将多行插入 MySQL