求助:C#实现Bookings表双字段联合防重复预订校验
解决重复预订校验问题
原始代码存在的问题
- SQL注入风险与格式错误:直接拼接字符串生成SQL语句,不仅易遭SQL注入攻击,还可能因日期时间格式不匹配导致查询失败。
- 查询逻辑低效:
ExecuteScalar()仅返回查询结果的第一行第一列,无法同时获取两个字段校验,且没必要返回具体字段值。 - 判断逻辑错误:仅检查日期字段,未同时校验时间,且
else if存在语法错误。
修正后的实现方案
核心思路:通过参数化查询安全传递日期时间参数,同时查询数据库中是否存在匹配记录(只需判断存在性,无需返回具体字段)。
// 检查重复预订逻辑 using (SqlConnection sc = new SqlConnection(ConfigurationManager.ConnectionStrings["SimpsonsConnection"].ConnectionString)) { sc.Open(); // 使用参数化查询,避免SQL注入并确保类型匹配 string checkQuery = "SELECT COUNT(*) FROM Bookings WHERE DateOfBooking = @DateOfBooking AND TimeOfBooking = @TimeOfBooking"; SqlCommand checkCommand = new SqlCommand(checkQuery, sc); // 绑定日期参数(直接使用DateTimePicker的Value属性,避免格式问题) checkCommand.Parameters.AddWithValue("@DateOfBooking", dtp1.Value); // 校验并转换时间输入 DateTime timeBooking; if (!DateTime.TryParse(txtTimeOfBooking.Text, out timeBooking)) { MessageBox.Show("请输入有效的时间格式!"); return; } checkCommand.Parameters.AddWithValue("@TimeOfBooking", timeBooking); // 获取匹配的记录数量 int existingBookings = (int)checkCommand.ExecuteScalar(); sc.Close(); if (existingBookings > 0) { MessageBox.Show("该预订时段已被占用,请选择其他时段!"); } else { // 此处执行新增预订的逻辑 // ... } }
额外说明
- 参数化查询:必须使用参数而非字符串拼接,这是防止SQL注入的关键,同时能自动处理日期时间类型的格式转换,避免因区域设置不同导致的查询错误。
- 时间输入校验:添加
DateTime.TryParse确保文本框输入的时间格式有效,避免无效值传入数据库引发异常。如果你的TimeOfBooking字段是SQL Server的time类型,可将代码改为TimeSpan.TryParse来转换:TimeSpan timeBooking; if (!TimeSpan.TryParse(txtTimeOfBooking.Text, out timeBooking)) { MessageBox.Show("请输入有效的时间格式!"); return; } checkCommand.Parameters.AddWithValue("@TimeOfBooking", timeBooking); - 性能优化:使用
COUNT(*)判断记录存在性,比返回具体字段更高效,数据库只需统计匹配行数即可。
内容的提问来源于stack exchange,提问作者Jack___
相关产品推荐
相关产品推荐

