VB.NET向SQL Server传递日期时间值如何避免转换错误?
问题描述
使用Visual Basic.NET、SQL Server 2016、Visual Studio 2017开发Windows窗体程序时遇到日期插入错误:
- 已在SQL Server Management Studio执行
set dateformat mdy,但表中日期仍显示为2022-07-17 00:00:00.000格式 - 运行项目插入数据时触发类型转换错误,提示varchar转datetime超出范围
- 此前使用MySQL时无此问题,不清楚如何在数据库或Visual Studio中调整日期格式适配SQL Server
错误代码
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click Dim someid As Integer = TextCode.Text Dim descri As String = TextDescription.Text Dim somedate As DateTime = DateTimePickerinsert.Text Dim value As String = TextValue.Text Dim stock As String = TextStock.Text Dim warehouse As String = ComboWarehouse.Text con.Open() Dim command As New SqlCommand("Insert into Item values('" & someid & "','" & descri & "','" & somedate & "','" & value & "','" & stock & "','" & warehouse & "')", con) command.ExecuteNonQuery() con.Close() MessageBox.Show("Inserted succesfully") LoadDataInGrid() End Sub
报错信息
System.Data.SqlClient.SqlException: '将varchar数据类型转换为datetime数据类型时产生了超出范围的值。
语句已终止。' 错误发生在command.ExecuteNonQuery()行
解决方法
核心问题:字符串拼接导致的日期格式歧义
当前代码将DateTime对象转成字符串后直接拼入SQL语句,SQL Server会根据会话的日期格式解析字符串,一旦本地日期格式与SQL Server会话格式不匹配(比如本地用dd/mm/yyyy,SQL Server按mm/dd/yyyy解析,17月就会超出范围),就会触发错误。同时这种写法还存在SQL注入风险。正确方案:使用参数化查询
不要直接拼接字符串,改用SqlParameter传递参数,DateTime对象会直接以SQL Server可识别的方式传递,彻底避免格式问题。修改后的代码如下:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click ' 先验证ID格式有效性 Dim someid As Integer If Not Integer.TryParse(TextCode.Text, someid) Then MessageBox.Show("请输入有效的ID") Return End If Dim descri As String = TextDescription.Text ' 直接获取DateTimePicker的Value属性,避免字符串转换 Dim somedate As DateTime = DateTimePickerinsert.Value Dim value As String = TextValue.Text Dim stock As String = TextStock.Text Dim warehouse As String = ComboWarehouse.Text ' 使用Using语句自动释放连接资源,防止连接泄漏 Using con As New SqlConnection("你的数据库连接字符串") con.Open() ' 明确指定表列名,避免表结构变更引发错误 Dim command As New SqlCommand("INSERT INTO Item (ID列名, 描述列名, 日期列名, 值列名, 库存列名, 仓库列名) VALUES (@ID, @Descri, @SomeDate, @Value, @Stock, @Warehouse)", con) ' 添加参数并指定类型(可选,但更严谨) command.Parameters.Add("@ID", SqlDbType.Int).Value = someid command.Parameters.Add("@Descri", SqlDbType.VarChar).Value = descri command.Parameters.Add("@SomeDate", SqlDbType.DateTime).Value = somedate command.Parameters.Add("@Value", SqlDbType.VarChar).Value = value command.Parameters.Add("@Stock", SqlDbType.VarChar).Value = stock command.Parameters.Add("@Warehouse", SqlDbType.VarChar).Value = warehouse command.ExecuteNonQuery() MessageBox.Show("插入成功") LoadDataInGrid() End Using End Sub
注意:需将SQL语句中的ID列名等占位符替换为你Item表中实际的字段名称。
- 关于SQL Server日期显示的说明
SQL Server中datetime类型的存储格式是固定的,你看到的2022-07-17 00:00:00.000仅为显示格式,与存储逻辑无关。set dateformat mdy仅影响当前会话中字符串转datetime的解析规则,不会改变存储和查询后的显示格式。
内容的提问来源于stack exchange,提问作者spiritedHunter
相关产品推荐
相关产品推荐

