【发布时间】: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