【问题标题】:SmallDateTime Overflow only on remote test serverSmallDateTime 仅在远程测试服务器上溢出
【发布时间】:2017-04-18 02:46:49
【问题描述】:

我有一个应用程序,用户将数据 excel 文件上传到数据库表,所有列的顺序与 excel 和数据库表的顺序相同。

我使用 OpenXML SDK 进行解析并使用 switch/case 来调整某些字段类型以避免错误。

 public static object ConvertToExpectedType(string value, SqlDbType sqlType)
        {
            switch (sqlType)
            {
                ...

            case SqlDbType.SmallDateTime:
            case SqlDbType.DateTime:
            case SqlDbType.Date:
            case SqlDbType.DateTime2:
                return ParseExcelDate(value, SqlDbType.DateTime);
            case SqlDbType.Time:
                return ParseExcelDate(value, SqlDbType.Time).TimeOfDay;

            ...

        }
    }

    public static DateTime ParseExcelDate(this string date, SqlDbType type)
    {
        if (date.Equals("null", StringComparison.InvariantCultureIgnoreCase))
            return new DateTime(1900, 01, 01);

        DateTime dt;

        if (DateTime.TryParse(date, culture, DateTimeStyles.NoCurrentDateDefault,out dt))
        {
            return dt;
        }

        double oaDate;
        if (double.TryParse(date,  NumberStyles.Float, culture,out oaDate))
        {
            return DateTime.FromOADate(oaDate);
        }

        return new DateTime(1900, 01, 01);
    }

在我的开发环境(发布和调试模式)中,应用程序工作得很好,但是当我将它发布到我的服务器时,我从其中一个文件中得到了这个异常:

SqlDbType.SmallDateTime 溢出。值“12/31/1899 00:00:00”已出 的范围。必须在 1/1/1900 12:00:00 AM 和 6/6/2079 11:59:59 之间 下午。;

即使我在 VS 中将连接字符串设置为远程数据库,应用程序也能正常工作。

以前有人遇到过这个问题吗? 任何想法如何解决它或进行不同的测试以确定问题出在哪里?

完全例外

System.OverflowException: SqlDbType.SmallDateTime overflow.  Value '12/31/1899 00:00:00' is out of range.  Must be between 1/1/1900 12:00:00 AM and 6/6/2079 11:59:59 PM.
   at System.Data.SqlClient.TdsParser.WriteUnterminatedValue(Object value, MetaType type, Byte scale, Int32 actualLength, Int32 encodingByteSize, Int32 offset, TdsParserStateObject stateObj, Int32 paramSize, Boolean isDataFeed)
   at System.Data.SqlClient.TdsParser.WriteBulkCopyValue(Object value, SqlMetaDataPriv metadata, TdsParserStateObject stateObj, Boolean isSqlType, Boolean isDataFeed, Boolean isNull)
   at System.Data.SqlClient.SqlBulkCopy.ReadWriteColumnValueAsync(Int32 col)
   at System.Data.SqlClient.SqlBulkCopy.CopyColumnsAsync(Int32 col, TaskCompletionSource`1 source)
   at System.Data.SqlClient.SqlBulkCopy.CopyRowsAsync(Int32 rowsSoFar, Int32 totalRows, CancellationToken cts, TaskCompletionSource`1 source)
   at System.Data.SqlClient.SqlBulkCopy.CopyBatchesAsyncContinued(BulkCopySimpleResultSet internalResults, String updateBulkCommandText, CancellationToken cts, TaskCompletionSource`1 source)
   at System.Data.SqlClient.SqlBulkCopy.CopyBatchesAsync(BulkCopySimpleResultSet internalResults, String updateBulkCommandText, CancellationToken cts, TaskCompletionSource`1 source)
   at System.Data.SqlClient.SqlBulkCopy.WriteToServerInternalRestContinuedAsync(BulkCopySimpleResultSet internalResults, CancellationToken cts, TaskCompletionSource`1 source)
   at System.Data.SqlClient.SqlBulkCopy.WriteToServerInternalRestAsync(CancellationToken cts, TaskCompletionSource`1 source)
   at System.Data.SqlClient.SqlBulkCopy.WriteToServerInternalAsync(CancellationToken ctoken)
   at System.Data.SqlClient.SqlBulkCopy.WriteRowSourceToServerAsync(Int32 columnCount, CancellationToken ctoken)
   at System.Data.SqlClient.SqlBulkCopy.WriteToServer(DataTable table, DataRowState rowState)
   at PVINOVA_FIleUploader_v1._0.Models.MSqlServer.MSqlServerDbContext.InsertRecordsSqlBulkCopy(DataTable dt, SqlTransaction transaction, List`1 TableSchema, FileType fileType, String errLogPath)

提前致谢!

更新!!!找到有问题的字段

我将有问题的批次提取到 CSV 文件以找出错误的日期。

原始文件的值是 1900 年 1 月 1 日,但在字段处理后(上面提到的方法 ParseExcelDate)不知何故该字段变为 12/31/1899。

另外,其他日期值与原始文件匹配

我考虑了两种可能的解决方案,但我仍然不明白为什么会发生这种情况,所以我对修复感到不舒服。有什么想法吗?

【问题讨论】:

  • 发生此错误时,您检查变量值了吗?
  • 您能否捕捉到发布后抛出错误的哪一行(建议使用 try...catch 块并在自定义错误页面中显示整个错误消息)?还有哪种Excel数据触发异常?如有必要,包括错误堆栈跟踪。
  • 抱歉延迟回复。我正在处理的文件有 42k 行,我确实设法将有问题的 1k 行的批次提取到 CSV,但是所有 smalldatetime 列(只有 2 个)都可以,并且只有一个值作为 1900 启动-01-01,有些被设置为“Null”,我将其转换为默认值 1900... *但有些东西引起了我的注意,csv 文件在某些​​字段中出现故障,我的意思是,列移位可能是问题的根源,或者可能只是将数据表转换为 csv 的代码错误。
  • @TetsuyaYamamoto 我终于设法找到有问题的字段。检查帖子更新。

标签: c# asp.net sql-server


【解决方案1】:

使用 OpenXML SDK 从 excel 解析值时,日期以浮点数形式出现(即 45231,4221)。由于字段值为 1900-01-01 = 1.0 .Net 转换为它自己的默认值,即 1899-12-30 = 1.0。

为了解决这个问题,我对“ParseExcelDate”方法中的第一个 If 语句又设置了一个条件

public static DateTime ParseExcelDate(this string date, SqlDbType type)
        {
            if (date.Equals("null", StringComparison.InvariantCultureIgnoreCase) || date.Equals("1.0"))
                return new DateTime(1900, 01, 01);
...

这篇文章帮助我找到了这个解决方案:What is equivalent of DateTime.ToOADate() in javascript?

但我仍然不知道它是如何在我的本地机器上工作的,而不是在服务器上

【讨论】:

    猜你喜欢
    • 2013-03-02
    • 2021-01-31
    • 2013-03-03
    • 2011-07-22
    • 2015-11-13
    • 2013-05-17
    • 2021-12-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多