我有一个应用程序,用户将数据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之间 PM;
即使我将连接字符串设置为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文件,找出错误的日期。
原始文件的值为01/01/1900,但在字段上的处理(上面提到的方法ParseExcelDate)后,字段变为12/31/1899。
此外,其他日期值与原始文件
匹配我想到了两种可能的解决方案,但我仍然不明白为什么会发生这种情况,所以我对修复感到不舒服。有什么想法吗?
答案 0 :(得分:0)
使用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?
但我仍然不知道它在我的本地机器上是如何工作的,而不是在服务器上