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

使用VB.NET将Excel导入SQL Server时日期转换失败问题求助

问题根因
  • 日期转换逻辑依赖系统区域设置:Convert.ToDateTime()和ToShortDateString()方法的输出格式受运行设备的系统区域配置影响,比如部分区域默认输出MM/dd/yyyy格式的日期,和SQL Server期望的格式不匹配就会触发转换失败。
  • OLEDB读取Excel列类型判断异常:默认情况下OLEDB驱动会根据Excel前8行数据自动判断列的数据类型,如果你修改数据后某行日期的单元格格式和前8行不一致,驱动可能会将该单元格读取为乱码文本或DBNull,转换时直接报错。
  • SQL字符串拼接风险:直接拼接日期字符串到SQL语句中,没有统一的日期格式约束,不同环境下极易出现格式兼容问题,同时还存在SQL注入漏洞。
修复方案

1. 调整Excel连接字符串

在Excel的OLEDB连接字符串中加入IMEX=1参数,强制驱动将所有列按文本格式读取,避免自动类型判断导致的读取异常,参考连接字符串:

Provider=Microsoft.ACE.OLEDB.12.0;Data Source=你的Excel文件路径;Extended Properties="Excel 12.0 Xml;HDR=YES;IMEX=1";

2. 替换日期转换逻辑

使用DateTime.TryParseExact方法指定固定的yyyy-MM-dd格式进行日期转换,避免系统区域影响,同时增加空值/格式异常判断,可提前定位出错行。

3. 改用参数化查询执行插入

替换字符串拼接SQL的方式,通过参数传递日期和其他字段值,彻底解决日期格式兼容问题。

修改后的参考代码
Try
    OLEcon.Open()
    With OLEcmd
        .Connection = OLEcon
        .CommandText = "select * from [Sheet1$]"
    End With
    OLEda.SelectCommand = OLEcmd
    OLEda.Fill(OLEdt)

    ' 提前定义参数化SQL,不需要拼接变量
    Dim insertSql As String = "INSERT INTO MasterStaffListTry (EENo,Name,Age,AgeCategory,Gender,Ethnicity,Grade,Category,Department,Position,ReportingTo,LastEmploymentDate,DateJoin,LOCUM,Status) VALUES (@EENo,@Name,@Age,@AgeCategory,@Gender,@Ethnicity,@Grade,@Category,@Department,@Position,@ReportingTo,@LastEmploymentDate,@DateJoin,@LOCUM,@Status)"

    For Each r As DataRow In OLEdt.Rows
        ' 年龄转换增加异常判断
        Dim intAge As Integer
        If Not Integer.TryParse(r(2)?.ToString(), intAge) Then
            ' 可在此处加日志记录该行年龄格式错误,跳过该行继续执行
            Continue For
        End If

        ' 日期转换指定固定格式,不受系统区域影响
        Dim dateLED As Date
        Dim ledStr = r(11)?.ToString().Trim()
        If Not DateTime.TryParseExact(ledStr, "yyyy-MM-dd", Globalization.CultureInfo.InvariantCulture, Globalization.DateTimeStyles.None, dateLED) Then
            ' 可在此处加日志记录该行LastEmploymentDate格式错误,跳过该行继续执行
            Continue For
        End If

        Dim dateDJ As Date
        Dim djStr = r(12)?.ToString().Trim()
        If Not DateTime.TryParseExact(djStr, "yyyy-MM-dd", Globalization.CultureInfo.InvariantCulture, Globalization.DateTimeStyles.None, dateDJ) Then
            ' 可在此处加日志记录该行DateJoin格式错误,跳过该行继续执行
            Continue For
        End If

        ' 调用参数化方法执行插入,需对应修改saveData方法支持传入参数数组
        Dim params As New List(Of SqlParameter) From {
            New SqlParameter("@EENo", If(r(0)?.ToString(), DBNull.Value)),
            New SqlParameter("@Name", If(r(1)?.ToString(), DBNull.Value)),
            New SqlParameter("@Age", intAge),
            New SqlParameter("@AgeCategory", If(r(3)?.ToString(), DBNull.Value)),
            New SqlParameter("@Gender", If(r(4)?.ToString(), DBNull.Value)),
            New SqlParameter("@Ethnicity", If(r(5)?.ToString(), DBNull.Value)),
            New SqlParameter("@Grade", If(r(6)?.ToString(), DBNull.Value)),
            New SqlParameter("@Category", If(r(7)?.ToString(), DBNull.Value)),
            New SqlParameter("@Department", If(r(8)?.ToString(), DBNull.Value)),
            New SqlParameter("@Position", If(r(9)?.ToString(), DBNull.Value)),
            New SqlParameter("@ReportingTo", If(r(10)?.ToString(), DBNull.Value)),
            New SqlParameter("@LastEmploymentDate", dateLED),
            New SqlParameter("@DateJoin", dateDJ),
            New SqlParameter("@LOCUM", If(r(13)?.ToString(), DBNull.Value)),
            New SqlParameter("@Status", If(r(14)?.ToString(), DBNull.Value))
        }

        resul = saveData(insertSql, params)
        If resul Then
            Timer1.Start()
        End If
    Next
Catch ex As Exception
    ' 全局异常捕获记录错误日志
Finally
    OLEcon.Close()
End Try

内容的提问来源于stack exchange,提问作者lowkey

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 08:24:02