PHP MySQL 插入多条数据(批量插入)
在实际开发中,我们经常需要向数据库中批量插入多条数据。批量插入不仅能提高性能,还能减少数据库的压力。通过 PHP 和 MySQL,我们可以使用 MySQLi 或 PDO 完成批量插入操作。
下面将全面解析 如何批量插入多条数据,常见错误和解决方案,以及 最佳实践。
1. 使用 MySQLi 插入多条数据
1.1 MySQLi 过程化风格(插入多条数据)
<?php
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "my_database";
// 连接 MySQL
$conn = mysqli_connect($servername, $username, $password, $dbname);
// 检测连接
if (!$conn) {
die("连接失败: " . mysqli_connect_error());
}
// 批量插入 SQL
$sql = "INSERT INTO users (username, email, password) VALUES
('user1', 'user1@example.com', 'password123'),
('user2', 'user2@example.com', 'password456'),
('user3', 'user3@example.com', 'password789')";
if (mysqli_query($conn, $sql)) {
echo "多条记录插入成功";
} else {
echo "错误: " . mysqli_error($conn);
}
// 关闭连接
mysqli_close($conn);
?>
📌 解析:
- 我们在
INSERT INTO语句中使用 多个VALUES来批量插入数据。 - 每条数据用逗号分隔。
1.2 MySQLi 面向对象风格(插入多条数据)
<?php
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "my_database";
// 创建连接
$conn = new mysqli($servername, $username, $password, $dbname);
// 检测连接
if ($conn->connect_error) {
die("连接失败: " . $conn->connect_error);
}
// 批量插入 SQL
$sql = "INSERT INTO users (username, email, password) VALUES
('user1', 'user1@example.com', 'password123'),
('user2', 'user2@example.com', 'password456'),
('user3', 'user3@example.com', 'password789')";
if ($conn->query($sql) === TRUE) {
echo "多条记录插入成功";
} else {
echo "错误: " . $conn->error;
}
// 关闭连接
$conn->close();
?>
📌 面向对象风格:
- 使用
$conn->query($sql)执行 SQL 查询。
2. 使用 PDO 插入多条数据(推荐)
2.1 PDO 直接执行批量插入
<?php
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "my_database";
try {
// 连接 MySQL
$pdo = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// 批量插入 SQL
$sql = "INSERT INTO users (username, email, password) VALUES
(:username1, :email1, :password1),
(:username2, :email2, :password2),
(:username3, :email3, :password3)";
$stmt = $pdo->prepare($sql);
// 绑定参数并执行
$stmt->bindParam(':username1', $username1);
$stmt->bindParam(':email1', $email1);
$stmt->bindParam(':password1', $password1);
$stmt->bindParam(':username2', $username2);
$stmt->bindParam(':email2', $email2);
$stmt->bindParam(':password2', $password2);
$stmt->bindParam(':username3', $username3);
$stmt->bindParam(':email3', $email3);
$stmt->bindParam(':password3', $password3);
// 设置数据并执行
$username1 = 'user1'; $email1 = 'user1@example.com'; $password1 = 'password123';
$username2 = 'user2'; $email2 = 'user2@example.com'; $password2 = 'password456';
$username3 = 'user3'; $email3 = 'user3@example.com'; $password3 = 'password789';
$stmt->execute();
echo "多条记录插入成功";
} catch (PDOException $e) {
echo "错误: " . $e->getMessage();
}
// 关闭连接
$pdo = null;
?>
📌 解析:
- 我们在
INSERT INTO中使用 命名参数(:username1,:email1)。 - 通过 绑定参数,防止 SQL 注入。
- 批量插入时,数据以不同的变量传递给 SQL 语句。
2.2 PDO 使用批量数据循环插入(更高效)
<?php
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "my_database";
try {
// 连接 MySQL
$pdo = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// 预处理 SQL
$sql = "INSERT INTO users (username, email, password) VALUES (:username, :email, :password)";
$stmt = $pdo->prepare($sql);
// 批量数据
$data = [
['user1', 'user1@example.com', 'password123'],
['user2', 'user2@example.com', 'password456'],
['user3', 'user3@example.com', 'password789']
];
// 使用循环插入多条数据
foreach ($data as $row) {
$stmt->bindParam(':username', $row[0]);
$stmt->bindParam(':email', $row[1]);
$stmt->bindParam(':password', $row[2]);
$stmt->execute();
}
echo "批量插入数据成功";
} catch (PDOException $e) {
echo "错误: " . $e->getMessage();
}
// 关闭连接
$pdo = null;
?>
📌 优化:
- 通过循环处理批量数据,可以动态插入任意数量的记录。
- 使用
bindParam()防止 SQL 注入,并确保执行效率。
3. 使用事务(Transaction)插入多条数据
在批量插入大量数据时,使用事务能够确保数据一致性。事务可以确保批量操作要么全部成功,要么全部失败。
3.1 PDO 使用事务批量插入
<?php
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "my_database";
try {
// 连接 MySQL
$pdo = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// 开始事务
$pdo->beginTransaction();
// 预处理 SQL
$sql = "INSERT INTO users (username, email, password) VALUES (:username, :email, :password)";
$stmt = $pdo->prepare($sql);
// 批量数据
$data = [
['user1', 'user1@example.com', 'password123'],
['user2', 'user2@example.com', 'password456'],
['user3', 'user3@example.com', 'password789']
];
// 循环插入数据
foreach ($data as $row) {
$stmt->bindParam(':username', $row[0]);
$stmt->bindParam(':email', $row[1]);
$stmt->bindParam(':password', $row[2]);
$stmt->execute();
}
// 提交事务
$pdo->commit();
echo "事务成功:批量插入数据";
} catch (PDOException $e) {
// 回滚事务
$pdo->rollBack();
echo "错误: " . $e->getMessage();
}
// 关闭连接
$pdo = null;
?>
📌 解析:
- 使用
$pdo->beginTransaction()启动事务。 commit()提交事务,rollBack()回滚事务,保证数据一致性。
4. 常见错误及解决方案
4.1 “Duplicate entry for key ‘PRIMARY'”
原因:插入数据时主键重复。
解决方案:
- 确保主键是
AUTO_INCREMENT。 - 如果数据包含重复主键,使用
INSERT IGNORE或ON DUPLICATE KEY UPDATE。
4.2 “Field ’email’ doesn’t have a default value”
原因:缺少必填字段的值。
解决方案:
- 确保插入所有 **`
NOT NULL`** 字段的值,或修改数据库表结构使其允许空值。
总结
| 方式 | 代码 | 是否推荐 |
|---|---|---|
| MySQLi 过程化 | mysqli_query($conn, $sql); | ❌ |
| MySQLi 面向对象 | $conn->query($sql); | ❌ |
| PDO 直接执行 | $pdo->exec($sql); | ❌ |
| PDO 循环插入 | $stmt->execute($row); | ✅ |
| PDO 事务 | $pdo->beginTransaction(); | ✅ |
更多详细内容请关注其他相关文章!