Skip to content

12.5 修改数据 update

UPDATE 语句基础

UPDATE 语句用于修改数据库表中已存在的记录,是数据库操作中常用的操作之一。

基本语法

sql
UPDATE table_name SET column1 = value1, column2 = value2, ... WHERE condition;

基本更新

1. 更新单条记录

php
<?php
require_once 'db.php';
$conn = getDbConnection();

// 更新单条记录
$sql = "UPDATE users SET age = 26, email = 'updated@example.com' WHERE id = 1";

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 = "UPDATE users SET age = age + 1 WHERE age < 18";

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("UPDATE users SET age = ?, email = ? WHERE id = ?");
$stmt->bind_param("isi", $age, $email, $id);

// 设置参数并执行
$age = 27;
$email = 'newemail@example.com';
$id = 1;

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("UPDATE users SET age = ? WHERE id = ?");
$stmt->bind_param("ii", $age, $id);

// 要更新的数据
$updates = [
    [28, 2],
    [29, 3],
    [30, 4]
];

// 执行多次更新
$successCount = 0;
foreach ($updates as $update) {
    $age = $update[0];
    $id = $update[1];
    
    if ($stmt->execute()) {
        $successCount++;
    }
}

echo "成功更新 $successCount 条记录";

$stmt->close();
$conn->close();
?>

更新数据与表单结合

1. 基本表单处理

php
<?php
require_once 'db.php';
$conn = getDbConnection();

$errors = [];
$success = false;
$user = null;

// 获取用户信息
if (isset($_GET['id'])) {
    $id = (int)$_GET['id'];
    $stmt = $conn->prepare("SELECT * FROM users WHERE id = ?");
    $stmt->bind_param("i", $id);
    $stmt->execute();
    $result = $stmt->get_result();
    
    if ($result->num_rows > 0) {
        $user = $result->fetch_assoc();
    } else {
        $errors[] = '用户不存在';
    }
    
    $stmt->close();
}

if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($user)) {
    // 表单验证
    if (empty($_POST['username'])) {
        $errors[] = '用户名不能为空';
    }
    
    if (empty($_POST['email'])) {
        $errors[] = '邮箱不能为空';
    } else if (!filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)) {
        $errors[] = '邮箱格式不正确';
    }
    
    if (empty($errors)) {
        // 准备语句
        $stmt = $conn->prepare("UPDATE users SET username = ?, email = ? WHERE id = ?");
        $stmt->bind_param("ssi", $username, $email, $id);
        
        // 设置参数
        $username = htmlspecialchars($_POST['username']);
        $email = htmlspecialchars($_POST['email']);
        
        if ($stmt->execute()) {
            $success = true;
            // 重新获取用户信息
            $stmt = $conn->prepare("SELECT * FROM users WHERE id = ?");
            $stmt->bind_param("i", $id);
            $stmt->execute();
            $result = $stmt->get_result();
            $user = $result->fetch_assoc();
        } else {
            $errors[] = '更新失败: ' . $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; }
        input { width: 100%; padding: 10px; margin: 5px 0; }
        input[type="submit"] { background-color: #4CAF50; color: white; border: none; cursor: pointer; }
    </style>
</head>
<body>
    <h2>编辑用户</h2>
    
    <?php if (!empty($errors)): ?>
        <div class="error">
            <ul>
                <?php foreach ($errors as $error): ?>
                    <li><?php echo $error; ?></li>
                <?php endforeach; ?>
            </ul>
        </div>
    <?php endif; ?>
    
    <?php if ($success): ?>
        <div class="success">
            用户更新成功!
        </div>
    <?php endif; ?>
    
    <?php if ($user): ?>
        <form action="" method="post">
            <label>用户名: <input type="text" name="username" value="<?php echo $user['username']; ?>"></label><br>
            <label>邮箱: <input type="email" name="email" value="<?php echo $user['email']; ?>"></label><br>
            <input type="submit" value="更新用户">
        </form>
    <?php endif; ?>
</body>
</html>

更新数据时的注意事项

1. WHERE 子句

非常重要:如果省略 WHERE 子句,UPDATE 语句将更新表中的所有记录!

php
// 危险!会更新所有记录
$sql = "UPDATE users SET age = 30";

// 安全:只更新指定记录
$sql = "UPDATE users SET age = 30 WHERE id = 1";

2. 数据类型匹配

确保更新的值与表字段的数据类型匹配:

  • 字符串类型:使用引号包围
  • 数字类型:直接使用,不使用引号
  • 日期类型:使用引号包围,格式为 'YYYY-MM-DD'
  • 布尔类型:使用 1 或 0

3. 转义特殊字符

使用预处理语句或 mysqli_real_escape_string 函数转义特殊字符:

php
// 使用 mysqli_real_escape_string
$username = mysqli_real_escape_string($conn, $_POST['username']);
$sql = "UPDATE users SET username = '$username' WHERE id = 1";

4. 处理 NULL 值

要将字段设置为 NULL,使用 NULL 关键字(不带引号):

php
$sql = "UPDATE users SET age = NULL WHERE id = 1";

// 使用预处理语句
$stmt = $conn->prepare("UPDATE users SET age = ? WHERE id = ?");
$age = null;
$stmt->bind_param("ii", $age, $id);

事务处理

对于需要更新多条相关记录的情况,使用事务确保数据一致性:

php
<?php
require_once 'db.php';
$conn = getDbConnection();

// 开始事务
$conn->begin_transaction();

try {
    // 更新用户信息
    $stmt = $conn->prepare("UPDATE users SET username = ? WHERE id = ?");
    $stmt->bind_param("si", $username, $userId);
    
    $username = "新用户名";
    $userId = 1;
    $stmt->execute();
    
    // 更新用户资料
    $stmt = $conn->prepare("UPDATE user_profiles SET full_name = ? WHERE user_id = ?");
    $stmt->bind_param("si", $fullName, $userId);
    
    $fullName = "新全名";
    $stmt->execute();
    
    // 提交事务
    $conn->commit();
    echo "用户信息更新成功";
} catch (mysqli_sql_exception $e) {
    // 回滚事务
    $conn->rollback();
    echo "更新失败: " . $e->getMessage();
}

$stmt->close();
$conn->close();
?>

高级更新技巧

1. 使用表达式更新

php
<?php
require_once 'db.php';
$conn = getDbConnection();

// 使用表达式更新
$sql = "UPDATE users SET age = age + 1, login_count = login_count + 1 WHERE id = 1";

if ($conn->query($sql) === TRUE) {
    echo "记录更新成功";
} else {
    echo "更新失败: " . $conn->error;
}

$conn->close();
?>

2. 使用 CASE 语句

php
<?php
require_once 'db.php';
$conn = getDbConnection();

// 使用 CASE 语句
$sql = "UPDATE users SET 
    status = CASE 
        WHEN age < 18 THEN '未成年'
        WHEN age >= 18 AND age < 60 THEN '成年'
        ELSE '老年'
    END
";

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 = "UPDATE users SET age = (SELECT AVG(age) FROM users) WHERE id = 1";

if ($conn->query($sql) === TRUE) {
    echo "记录更新成功";
} else {
    echo "更新失败: " . $conn->error;
}

$conn->close();
?>

最佳实践

  1. 使用 WHERE 子句:始终指定 WHERE 子句,避免更新所有记录
  2. 使用预处理语句:防止 SQL 注入攻击
  3. 数据验证:在更新前验证数据的有效性
  4. 错误处理:处理更新过程中的错误
  5. 事务处理:对于相关操作使用事务
  6. 检查影响行数:使用 $conn->affected_rows 检查更新是否成功
  7. 优化更新:只更新必要的字段,避免更新所有字段

练习

  1. 更新单条用户记录
  2. 更新多条用户记录
  3. 使用预处理语句更新数据
  4. 结合表单更新数据
  5. 使用事务更新相关数据
  6. 使用表达式和 CASE 语句更新数据

© 2026 编程马·菜鸟教程 版权所有