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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 00:06:25