如何在C#+MySQL中实现预约时段不重叠校验?
解决方案
首先你的代码存在SQL注入风险,必须先改成参数化查询,同时我们加入时段重叠校验逻辑:
核心逻辑:时段重叠判断
针对同一员工、同一天的预约,两个时段重叠的判定条件:
新预约的开始时间 < 已有预约的结束时间 并且 新预约的结束时间 > 已有预约的开始时间
修改后的完整代码
private void button1_Click(object sender, EventArgs e) { // 数据库连接字符串 string connStr = @"Data Source=DESKTOP-ELTMMCE;Initial Catalog=Stylogistx;Integrated Security=True"; // 解析预约日期并校验格式 if (!DateTime.TryParseExact(dateTbx.Text, "M/d/yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime appDate)) { MessageBox.Show("请输入正确格式的日期(如:10/5/2024)"); return; } // 检查日期是否为过去 if (appDate.Date < DateTime.Today.Date) { MessageBox.Show("预约日期不能是过去,请选择当前或未来日期。"); return; } // 拼接完整的预约时段(日期+时间) DateTime newStartTime = DateTime.Parse($"{appDate:yyyy-MM-dd} {apptStartTimePicker.Value:HH:mm:ss}"); DateTime newEndTime = DateTime.Parse($"{appDate:yyyy-MM-dd} {apptEndTimePicker.Value:HH:mm:ss}"); // 校验时段顺序合法性 if (newStartTime >= newEndTime) { MessageBox.Show("预约结束时间必须晚于开始时间。"); return; } // 校验员工选择状态 if (stylistCmboBx.SelectedValue == null) { MessageBox.Show("请选择服务员工。"); return; } int empId = Convert.ToInt32(stylistCmboBx.SelectedValue); // 检查是否存在重叠预约 bool hasOverlap = false; using (SqlConnection con = new SqlConnection(connStr)) { try { con.Open(); // 查询重叠预约的参数化SQL string checkOverlapSql = @" SELECT COUNT(1) FROM APPOINTMENT WHERE EMP_ID = @EmpId AND APP_DATE = @AppDate AND APP_STATUS = 'BOOKED' AND @NewStartTime < APP_ENDTIME AND @NewEndTime > APP_STARTTIME"; using (SqlCommand checkCmd = new SqlCommand(checkOverlapSql, con)) { checkCmd.Parameters.AddWithValue("@EmpId", empId); checkCmd.Parameters.AddWithValue("@AppDate", appDate); checkCmd.Parameters.AddWithValue("@NewStartTime", newStartTime); checkCmd.Parameters.AddWithValue("@NewEndTime", newEndTime); int overlapCount = Convert.ToInt32(checkCmd.ExecuteScalar()); hasOverlap = overlapCount > 0; } if (hasOverlap) { MessageBox.Show("该时段已有预约,无法提交,请选择其他时段。"); return; } // 插入新预约的参数化SQL string insertSql = @" INSERT INTO APPOINTMENT(APP_DATE, APP_STARTTIME, APP_ENDTIME, CLIENT_ID, EMP_ID, SERVICE_ID, APP_STATUS) VALUES (@AppDate, @StartTime, @EndTime, @ClientId, @EmpId, @ServiceId, 'BOOKED')"; using (SqlCommand insertCmd = new SqlCommand(insertSql, con)) { insertCmd.Parameters.AddWithValue("@AppDate", appDate); insertCmd.Parameters.AddWithValue("@StartTime", newStartTime); insertCmd.Parameters.AddWithValue("@EndTime", newEndTime); insertCmd.Parameters.AddWithValue("@ClientId", Convert.ToInt32(clientCmboBx.SelectedValue)); insertCmd.Parameters.AddWithValue("@EmpId", empId); insertCmd.Parameters.AddWithValue("@ServiceId", Convert.ToInt32(serviceCmboBx.SelectedValue)); insertCmd.ExecuteNonQuery(); MessageBox.Show("预约成功!"); } // 后续库存跟踪弹窗逻辑 DialogResult dialogResult = MessageBox.Show("跟踪库存?", "是否需要为本次预约跟踪库存?", MessageBoxButtons.YesNo); if (dialogResult == DialogResult.Yes) { this.Hide(); new Inventory_Tracking().Show(); } else { this.Hide(); new Appointment_Management().Show(); } } catch (Exception ex) { MessageBox.Show($"操作失败:{ex.Message}"); } } this.Hide(); }
关键改进点:
- 参数化查询:彻底避免SQL注入风险,同时解决日期/时间格式的兼容性问题
- 时段重叠校验:通过SQL直接查询同一员工、同一天、已预约状态下的重叠时段,效率更高
- 输入合法性检查:增加了日期格式校验、时段顺序校验、下拉框选中状态校验
- using语句:自动释放数据库连接和命令资源,避免资源泄漏
内容的提问来源于stack exchange,提问作者rdubya
相关产品推荐
相关产品推荐

