Appearance
12.6 删除数据 delete
DELETE 语句基础
DELETE 语句用于从数据库表中删除记录,是数据库操作中常用的操作之一。
基本语法
sql
DELETE FROM table_name WHERE condition;基本删除
1. 删除单条记录
php
<?php
require_once 'db.php';
$conn = getDbConnection();
// 删除单条记录
$sql = "DELETE FROM users WHERE id = 5";
if ($conn->query($sql) === TRUE) {
echo "记录删除成功,影响行数: " . $conn->affected_rows;
} else {
echo "删除失败: " . $conn->error;
}
$conn->close();
?>2. 删除多条记录
php
<?php
require_once 'db.php';
$conn = getDbConnection();
// 删除多条记录
$sql = "DELETE FROM users WHERE age < 18";
if ($conn->query($sql) === TRUE) {
echo "记录删除成功,影响行数: " . $conn->affected_rows;
} else {
echo "删除失败: " . $conn->error;
}
$conn->close();
?>3. 删除所有记录
php
<?php
require_once 'db.php';
$conn = getDbConnection();
// 删除所有记录(谨慎使用)
$sql = "DELETE FROM users";
if ($conn->query($sql) === TRUE) {
echo "所有记录删除成功,影响行数: " . $conn->affected_rows;
} else {
echo "删除失败: " . $conn->error;
}
$conn->close();
?>使用预处理语句
预处理语句可以防止 SQL 注入攻击,同时提高执行效率。
1. 删除单条记录
php
<?php
require_once 'db.php';
$conn = getDbConnection();
// 准备语句
$stmt = $conn->prepare("DELETE FROM users WHERE id = ?");
$stmt->bind_param("i", $id);
// 设置参数并执行
$id = 6;
if ($stmt->execute()) {
echo "记录删除成功,影响行数: " . $stmt->affected_rows;
} else {
echo "删除失败: " . $stmt->error;
}
$stmt->close();
$conn->close();
?>2. 批量删除
php
<?php
require_once 'db.php';
$conn = getDbConnection();
// 准备语句
$stmt = $conn->prepare("DELETE FROM users WHERE id = ?");
$stmt->bind_param("i", $id);
// 要删除的ID列表
$ids = [7, 8, 9];
// 执行多次删除
$successCount = 0;
foreach ($ids as $id) {
if ($stmt->execute()) {
$successCount++;
}
}
echo "成功删除 $successCount 条记录";
$stmt->close();
$conn->close();
?>删除数据与表单结合
1. 基本删除功能
php
<?php
require_once 'db.php';
$conn = getDbConnection();
$success = false;
$error = '';
if (isset($_GET['id'])) {
$id = (int)$_GET['id'];
// 准备语句
$stmt = $conn->prepare("DELETE FROM users WHERE id = ?");
$stmt->bind_param("i", $id);
if ($stmt->execute()) {
$success = true;
} else {
$error = '删除失败: ' . $stmt->error;
}
$stmt->close();
}
$conn->close();
?>
<!DOCTYPE html>
<html>
<head>
<title>删除用户</title>
<style>
body { font-family: Arial, sans-serif; max-width: 400px; margin: 0 auto; padding: 20px; }
.error { color: red; }
.success { color: green; }
.confirm { background-color: #f9f9f9; padding: 20px; border: 1px solid #ddd; border-radius: 5px; }
.button { padding: 10px 20px; margin: 5px; text-decoration: none; border-radius: 4px; }
.delete { background-color: #f44336; color: white; }
.cancel { background-color: #9e9e9e; color: white; }
</style>
</head>
<body>
<h2>删除用户</h2>
<?php if ($error): ?>
<div class="error">
<?php echo $error; ?>
</div>
<?php endif; ?>
<?php if ($success): ?>
<div class="success">
用户删除成功!
</div>
<a href="user_list.php" class="button cancel">返回用户列表</a>
<?php else: ?>
<div class="confirm">
<p>确定要删除这个用户吗?此操作不可恢复。</p>
<a href="?id=<?php echo $_GET['id']; ?>" class="button delete">确认删除</a>
<a href="user_list.php" class="button cancel">取消</a>
</div>
<?php endif; ?>
</body>
</html>删除数据时的注意事项
1. WHERE 子句
非常重要:如果省略 WHERE 子句,DELETE 语句将删除表中的所有记录!
php
// 危险!会删除所有记录
$sql = "DELETE FROM users";
// 安全:只删除指定记录
$sql = "DELETE FROM users WHERE id = 1";2. 外键约束
如果表之间存在外键关系,删除记录时需要考虑外键约束:
- CASCADE:删除主表记录时,自动删除从表相关记录
- SET NULL:删除主表记录时,将从表相关字段设为 NULL
- RESTRICT:如果存在从表相关记录,不允许删除主表记录
- NO ACTION:同 RESTRICT
3. 事务处理
对于需要删除多条相关记录的情况,使用事务确保数据一致性:
php
<?php
require_once 'db.php';
$conn = getDbConnection();
// 开始事务
$conn->begin_transaction();
try {
$userId = 10;
// 删除用户的订单
$stmt = $conn->prepare("DELETE FROM orders WHERE user_id = ?");
$stmt->bind_param("i", $userId);
$stmt->execute();
// 删除用户的资料
$stmt = $conn->prepare("DELETE FROM user_profiles WHERE user_id = ?");
$stmt->bind_param("i", $userId);
$stmt->execute();
// 删除用户
$stmt = $conn->prepare("DELETE FROM users WHERE id = ?");
$stmt->bind_param("i", $userId);
$stmt->execute();
// 提交事务
$conn->commit();
echo "用户及相关数据删除成功";
} catch (mysqli_sql_exception $e) {
// 回滚事务
$conn->rollback();
echo "删除失败: " . $e->getMessage();
}
$stmt->close();
$conn->close();
?>4. 性能考虑
- 批量删除:对于大量数据,使用批量删除比逐条删除更高效
- 索引:确保 WHERE 子句中的字段有索引,提高删除速度
- 限制删除:使用 LIMIT 子句限制删除的记录数
php
// 限制删除10条记录
$sql = "DELETE FROM users WHERE age < 18 LIMIT 10";软删除
在实际应用中,通常不直接删除数据,而是使用软删除(标记删除):
1. 添加删除标记字段
sql
ALTER TABLE users ADD COLUMN deleted_at TIMESTAMP NULL;2. 软删除实现
php
<?php
require_once 'db.php';
$conn = getDbConnection();
// 软删除
$id = 11;
$stmt = $conn->prepare("UPDATE users SET deleted_at = NOW() WHERE id = ?");
$stmt->bind_param("i", $id);
if ($stmt->execute()) {
echo "用户软删除成功";
} else {
echo "删除失败: " . $stmt->error;
}
$stmt->close();
$conn->close();
?>3. 查询未删除的记录
php
<?php
require_once 'db.php';
$conn = getDbConnection();
// 查询未删除的记录
$sql = "SELECT * FROM users WHERE deleted_at IS NULL";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
while ($row = $result->fetch_assoc()) {
echo "id: " . $row["id"] . " - 用户名: " . $row["username"] . "<br>";
}
} else {
echo "0 结果";
}
$result->free();
$conn->close();
?>最佳实践
- 使用 WHERE 子句:始终指定 WHERE 子句,避免删除所有记录
- 使用预处理语句:防止 SQL 注入攻击
- 事务处理:对于相关操作使用事务
- 软删除:考虑使用软删除替代物理删除
- 备份:在删除重要数据前进行备份
- 权限控制:限制删除操作的权限
- 确认机制:在删除前添加确认步骤
- 日志记录:记录删除操作的日志
练习
- 删除单条用户记录
- 删除多条用户记录
- 使用预处理语句删除数据
- 实现软删除功能
- 使用事务删除相关数据
- 实现带确认的删除功能
