SqlDateTime溢出异常排查:员工信息插入代码问题咨询
SqlDateTime溢出异常排查与解决
问题描述
执行员工信息插入操作时触发异常:
System.Data.SqlTypes.SqlTypeException: 'SqlDateTime溢出。必须介于1753年1月1日 00:00:00 和9999年12月31日之间'
提供的代码
数据访问层代码
public void InsertStaffInfo(StaffInformationModel staff) { try { DBConnection db = new DBConnection(); db.MyConn(); SqlCommand insertstaffinfo = new SqlCommand("sp_InsertUpdateDeleteStaffInfo", db.con); insertstaffinfo.CommandType = CommandType.StoredProcedure; insertstaffinfo.Parameters.AddWithValue("@STAFF_ID", 0); insertstaffinfo.Parameters.AddWithValue("@STAFF_FNAME", staff.STAFF_FNAME); insertstaffinfo.Parameters.AddWithValue("@STAFF_MNAME", staff.STAFF_MNAME); insertstaffinfo.Parameters.AddWithValue("@STAFF_LNAME", staff.STAFF_LNAME); insertstaffinfo.Parameters.AddWithValue("@STAFF_GENDER", staff.STAFF_GENDER); insertstaffinfo.Parameters.AddWithValue("@STAFF_DOB", staff.STAFF_DOB); insertstaffinfo.Parameters.AddWithValue("@STAFF_AGE", staff.STAFF_AGE); insertstaffinfo.Parameters.AddWithValue("@STAFF_OCCUPATION",staff.STAFF_OCCUPATION); insertstaffinfo.Parameters.AddWithValue("@STAFF_QUALIFICATION", staff.STAFF_QUALIFICATION); insertstaffinfo.Parameters.AddWithValue("@STAFF_DOJ", staff.STAFF_DOJ); insertstaffinfo.Parameters.AddWithValue("@STAFF_IMAGE", staff.STAFF_IMAGE); insertstaffinfo.Parameters.AddWithValue("@IMG_PATH", staff.IMAGE_PATH); insertstaffinfo.Parameters.AddWithValue("@CREATED_BY", staff.CREATED_BY); insertstaffinfo.Parameters.AddWithValue("@CREATED_ON", staff.CREATED_ON); insertstaffinfo.Parameters.AddWithValue("@IS_ACTIVE", staff.IS_ACTIVE); insertstaffinfo.Parameters.AddWithValue("@IS_DELETE", staff.IS_DELETE); insertstaffinfo.Parameters.AddWithValue("@MODE", 'I'); insertstaffinfo.ExecuteNonQuery(); } catch (SqlException ex) { string errorMsg = ""; errorMsg += ex.Message; throw new Exception(errorMsg); } }
日期赋值代码
insertstaff.STAFF_DOB = DateTime.ParseExact(txtdob.Text, "dd/MM/yyyy", null);
排查分析
这个异常的核心原因是传入SQL Server的DateTime值不在SQL支持的有效范围(1753-01-01 至 9999-12-31),常见触发场景:
- 日期解析失败,得到
DateTime.MinValue(0001-01-01),远早于SQL的最小日期阈值 STAFF_DOJ、CREATED_ON等其他日期字段未正确赋值,默认使用DateTime.MinValue- 输入的日期文本格式错误,解析出超出范围的无效日期
解决方案
1. 修复日期解析逻辑,添加异常处理
当前DateTime.ParseExact在输入格式不匹配时会直接抛出异常,且未处理解析失败的情况,改用DateTime.TryParseExact确保得到有效日期:
// 引入System.Globalization命名空间 using System.Globalization; // 替换原日期赋值代码 if (!DateTime.TryParseExact(txtdob.Text, "dd/MM/yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime dob)) { // 这里可以根据业务需求处理,比如提示用户或抛出明确错误 throw new ArgumentException("出生日期格式错误,请输入dd/MM/yyyy格式的日期(如:01/01/1990)"); } insertstaff.STAFF_DOB = dob;
2. 检查所有日期字段的赋值
确保所有日期类型的字段都被正确赋值,避免使用默认的DateTime.MinValue:
- 入职日期
STAFF_DOJ:参考上述解析逻辑,对前端输入做校验 - 创建时间
CREATED_ON:直接用当前时间赋值,推荐使用UTC时间避免时区问题:insertstaff.CREATED_ON = DateTime.UtcNow;
3. 优化数据库参数传递(避免隐式类型转换)
AddWithValue可能导致隐式类型转换问题,改用Add方法明确指定参数类型,同时处理空值/无效值:
// 替换原AddWithValue的日期参数赋值 insertstaffinfo.Parameters.Add("@STAFF_DOB", SqlDbType.DateTime).Value = staff.STAFF_DOB == DateTime.MinValue ? DBNull.Value : (object)staff.STAFF_DOB; insertstaffinfo.Parameters.Add("@STAFF_DOJ", SqlDbType.DateTime).Value = staff.STAFF_DOJ == DateTime.MinValue ? DBNull.Value : (object)staff.STAFF_DOJ; insertstaffinfo.Parameters.Add("@CREATED_ON", SqlDbType.DateTime).Value = staff.CREATED_ON == DateTime.MinValue ? DBNull.Value : (object)staff.CREATED_ON;
4. 升级数据库字段类型(可选)
如果业务需要支持更早的日期,可以将数据库中的日期字段类型从datetime改为datetime2,datetime2支持的范围是0001-01-01至9999-12-31,能从根源避免这类溢出问题。
内容的提问来源于stack exchange,提问作者Subhadip Sarangi
相关产品推荐
相关产品推荐

