如何在appointment表存在时段值时修改schedule表对应字段为00:00:00?
预约后标记Schedule表时段为不可用的实现方案
需求说明:
当slot time(时段)被插入至appointment表后,需将schedule表中对应的slot time字段值更新为00:00:00,使已预约时段在schedule表中标记为不可用。
原代码存在的问题
- 条件判断错误使用赋值运算符
=,而非比较运算符==/===,导致逻辑判断完全失效 - 全表查询
appointment和schedule数据,未通过WHERE条件过滤目标记录,效率极低 UPDATE语句缺少动态字段名,无法定位到对应时段字段- 循环逻辑冗余,多余的
break导致无法正确遍历匹配数据 - 未添加数据库操作的错误处理,难以排查执行异常
修正后的实现代码
<?php session_start(); // 从Session获取参数并做非空校验 $docid = $_SESSION['did'] ?? ''; $date = $_SESSION['dt'] ?? ''; $slot = $_SESSION['st'] ?? ''; if (empty($docid) || empty($date) || empty($slot)) { die('参数不完整,请检查Session数据'); } // 1. 验证当前预约记录存在(根据业务逻辑可选) $checkApptStmt = mysqli_prepare($conn, "SELECT 1 FROM `appointment` WHERE `docid` = ? AND `date` = ? AND `slot` = ?"); mysqli_stmt_bind_param($checkApptStmt, "sss", $docid, $date, $slot); mysqli_stmt_execute($checkApptStmt); $apptExists = mysqli_stmt_fetch($checkApptStmt); mysqli_stmt_close($checkApptStmt); if (!$apptExists) { die('未找到对应预约记录'); } // 2. 获取schedule表的时段字段名(匹配原代码中i=3到9的列) $scheduleFields = []; $descResult = mysqli_query($conn, "DESCRIBE `schedule`"); while ($field = mysqli_fetch_assoc($descResult)) { $scheduleFields[] = $field['Field']; } // 提取第3到第9个字段(索引从0开始,对应原代码的i=3到9) $targetSlotFields = array_slice($scheduleFields, 2, 7); // 3. 查找匹配时段并执行更新 $updateTemplate = "UPDATE `schedule` SET `%s` = '00:00:00' WHERE `docid` = ? AND `date` = ?"; foreach ($targetSlotFields as $fieldName) { // 查询当前字段的时段值 $checkSlotStmt = mysqli_prepare($conn, "SELECT `$fieldName` FROM `schedule` WHERE `docid` = ? AND `date` = ?"); mysqli_stmt_bind_param($checkSlotStmt, "ss", $docid, $date); mysqli_stmt_execute($checkSlotStmt); mysqli_stmt_bind_result($checkSlotStmt, $currentSlot); mysqli_stmt_fetch($checkSlotStmt); mysqli_stmt_close($checkSlotStmt); if ($currentSlot === $slot) { // 执行更新操作 $finalUpdateSql = sprintf($updateTemplate, $fieldName); $updateStmt = mysqli_prepare($conn, $finalUpdateSql); mysqli_stmt_bind_param($updateStmt, "ss", $docid, $date); $updateSuccess = mysqli_stmt_execute($updateStmt); mysqli_stmt_close($updateStmt); echo $updateSuccess ? "时段已成功标记为不可用" : "更新失败:" . mysqli_error($conn); break; } } ?>
关键优化点
- 使用预处理语句(Prepared Statements)防止SQL注入,提升代码安全性
- 通过
WHERE条件精准过滤目标记录,避免全表扫描,大幅提升查询效率 - 动态获取schedule表字段名,避免硬编码索引,增强代码可维护性
- 添加参数校验和错误反馈,提升代码健壮性
- 修正条件判断的运算符错误,确保逻辑正确性
内容的提问来源于stack exchange,提问作者Meghana
相关产品推荐
相关产品推荐

