You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 07:30:39