在MySQL中,插入单行数据的基本 INSERT INTO
语句结构如下:
INSERT INTO table_name (column1, column2, ...) VALUES ('value1', 'value2', ...);
而在PHP中,如果你想要使用 mysql_real_escape_string()
函数对用户输入的数据进行转义以防止SQL注入攻击(请注意,这个函数适用于非常老的 mysql_
扩展,现代应用应改用PDO或mysqli扩展配合预处理语句),代码可能会像这样:
// 不推荐使用mysql_扩展,这里仅作历史参考
$servername = "localhost";
$username = "username";
$password = "password";
$dbname = "database";
// 创建连接
$conn = mysql_connect($servername, $username, $password);
if (!$conn) {
die("Connection failed: " . mysql_error());
}
// 选择数据库
mysql_select_db($dbname, $conn);
// 假设我们从表单获取数据并进行转义
$name = mysql_real_escape_string($_POST['name']);
$email = mysql_real_escape_string($_POST['email']);
// 插入数据
$sql = "INSERT INTO users (name, email) VALUES ('$name', '$email')";
if (!mysql_query($sql, $conn)) {
// 错误处理
die("Error: " . mysql_error($conn));
} else {
echo "新记录插入成功!";
}
// 关闭连接
mysql_close($conn);
然而,从PHP 5.5.0开始,mysql_
扩展已被废弃,并在PHP 7中被移除,推荐使用 mysqli
或PDO扩展,并采用预处理语句,例如使用 mysqli
:
$servername = "localhost";
$username = "username";
$password = "password";
$dbname = "database";
// 创建连接
$conn = new mysqli($servername, $username, $password, $dbname);
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
// 预处理语句
$stmt = $conn->prepare("INSERT INTO users (name, email) VALUES (?, ?)");
$stmt->bind_param("ss", $name, $email);
// 假设我们从表单获取数据
$name = $_POST['name'];
$email = $_POST['email'];
// 执行插入
$stmt->execute();
if ($stmt->affected_rows > 0) {
echo "新记录插入成功!";
} else {
echo "插入失败!";
}
// 关闭声明
$stmt->close();
// 关闭连接
$conn->close();
对于批量插入数据,MySQL提供了 INSERT INTO ... VALUES (...), (...), ...;
的语法:
INSERT INTO table_name (column1, column2)
VALUES ('value1', 'value2'), ('value3', 'value4'), ...;
在PHP中,如果你需要执行批量插入,可以遍历数组并逐条插入,或者使用参数化查询构建多个值集:
$data = [
['John Doe', 'john@example.com'],
['Jane Smith', 'jane@example.com'],
];
$stmt = $conn->prepare("INSERT INTO users (name, email) VALUES (?, ?)");
foreach ($data as $row) {
$name = $row[0];
$email = $row[1];
$stmt->bind_param("ss", $name, $email);
$stmt->execute();
}
echo "批量插入完成!";
// 确保关闭声明和连接
$stmt->close();
$conn->close();
在上述示例中,没有直接使用 try-catch
块,但为了进行异常处理,你可以在PHP代码中将其包裹起来:
try {
// 连接数据库、准备语句等操作...
// 如果出现错误,会抛出异常
if ($conn->connect_error) {
throw new Exception("Connection failed: " . $conn->connect_error);
}
// 准备并执行插入操作...
} catch (Exception $e) {
echo "Error: " . $e->getMessage();
} finally {
// 不论是否发生异常,确保资源释放
if (isset($stmt)) {
$stmt->close();
}
if (isset($conn)) {
$conn->close();
}
}
mysqli_mulit_query批量插入数据,free_result()函数
在PHP中,如果你要使用 mysqli_multi_query()
函数来进行批量插入操作,可以将多个 INSERT INTO
语句组合成一个字符串,然后一次性发送到MySQL服务器执行。这里是一个示例:
$servername = "localhost";
$username = "username";
$password = "password";
$dbname = "database";
$conn = new mysqli($servername, $username, $password, $dbname);
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
// 假设有两个要插入的数据项
$insert_data = [
['John Doe', 'john@example.com'],
['Jane Smith', 'jane@example.com'],
];
// 构建批量插入的SQL语句
$sql = "";
foreach ($insert_data as $item) {
list($name, $email) = $item;
$sql .= "INSERT INTO users (name, email) VALUES ('{$name}', '{$email}'); ";
}
// 执行批量查询
if ($conn->multi_query($sql)) {
do {
// 使用store_result()或use_result()取决于你的需求,这里假设不需要存储结果
// (通常批量插入不需要获取结果集)
// free_result()在这里并不是必须的,因为并没有调用store_result()或use_result()
// 但如果之前进行了存储结果的操作,这里是应该调用free_result()来释放内存资源
// 如果你需要检查每个查询的错误或警告,可以通过下面的方式获取状态信息
if ($result = $conn->store_result()) {
// 检查错误或警告
while ($error = $result->fetch_row()) {
printf("Errormessage: %s\n", $error[2]);
}
$result->free();
}
if ($conn->more_results()) {
// 清理上一个查询可能产生的结果
// (实际上对于INSERT操作,这通常是不必要的)
// $conn->next_result();
}
} while ($conn->more_results() && $conn->next_result());
} else {
// 处理第一个错误的查询
echo "Error executing multi query: " . $conn->error;
}
$conn->close();
需要注意的是,在实际开发中,为了防止SQL注入,应当尽量避免直接拼接SQL语句,并且使用预处理语句(如上面提到的单条插入示例)。但在 mysqli_multi_query
场景下,如果确实需要进行批量插入且每条语句都是独立有效的,那么确保所有动态部分已经过适当转义或参数化处理。
另外,free_result()
函数用于释放结果集占用的内存资源,但在批量插入操作中并不常用,因为它不会产生结果集。只有当你通过 store_result()
或 use_result()
方法显式地存储了结果时,才需要调用 free_result()
来释放内存。对于 mysqli_multi_query()
中的非SELECT语句,通常不需要这样做。