解决Windows Form中Varchar转Datetime越界错误及日期格式统一问题
问题解决:日期类型转换错误及统一处理
错误原因
你遇到的「varchar转datetime值超出范围」错误,核心是直接将本地化显示的日期字符串拼接到SQL语句中:
- DataGridView显示的
02.12.2022 0:00:00是「日.月.年」的本地化格式,但SQL Server默认会将.分隔的字符串按「月.日.年」解析,当日期中的日数大于12时(比如19.09.1986),会被判定为无效月份,触发值超出范围的错误。同时直接拼接SQL还存在严重的SQL注入风险。
解决方案
1. 读取数据时:保留日期类型,统一显示格式
你读取数据时用record.GetDateTime(8)获取的DateTime类型是正确的,直接添加到DataGridView即可。要统一显示格式,只需设置对应列的显示样式,底层仍保留DateTime类型(不会丢失日期信息):
// 在DataGridView初始化或数据绑定完成后执行 dataGridView_Book.Columns[8].DefaultCellStyle.Format = "dd.MM.yyyy HH:mm:ss";
2. 更新数据时:使用参数化查询(核心解决方法)
绝对不要通过字符串拼接生成SQL语句,改用参数化查询直接传递DateTime类型,彻底规避格式不兼容问题,同时防止SQL注入:
修改更新代码如下:
var changeQuery = @"UPDATE Book SET Title_book = @Title, pages = @Pages, language_book = @Lang, format_book = @Format, ID_Genre = @Genre, ID_publishing_house = @PublicHouse, FILE_path = @FilePath, Publication_date = @PubDate WHERE ISBN = @ISBN"; using (var command = new SqlCommand(changeQuery, database.getConnection())) { // 添加参数,参数类型需与数据库列类型匹配 command.Parameters.AddWithValue("@Title", Title); command.Parameters.AddWithValue("@Pages", pages); command.Parameters.AddWithValue("@Lang", lang); command.Parameters.AddWithValue("@Format", format); command.Parameters.AddWithValue("@Genre", genre); command.Parameters.AddWithValue("@PublicHouse", public_house); command.Parameters.AddWithValue("@FilePath", file_path); // 直接获取单元格中的DateTime值,无需转换为字符串 command.Parameters.AddWithValue("@PubDate", (DateTime)dataGridView_Book.Rows[index].Cells[8].Value); command.Parameters.AddWithValue("@ISBN", ISBN); command.ExecuteNonQuery(); }
额外注意事项
如果日期列允许为空,需要处理DBNull情况:
var dateCellValue = dataGridView_Book.Rows[index].Cells[8].Value; command.Parameters.AddWithValue("@PubDate", dateCellValue == DBNull.Value ? (object)DBNull.Value : (DateTime)dateCellValue);
内容的提问来源于stack exchange,提问作者Dec
相关产品推荐
相关产品推荐

