2017-04-16 2 views
0

Ich habe eine Anwendung, wo der Benutzer eine Daten Excel-Datei in eine Datenbanktabelle hochlädt, sind alle Spalten in der gleichen Reihenfolge der Excel-und Datenbanktabelle.SmallDateTime Overflow nur auf Remote-Testserver

Ich benutze OpenXML SDK, um die Analyse und einen Schalter/Fall zu tun, um bestimmte Feldtypen anzupassen, um Fehler zu vermeiden.

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); 
    } 

In meinem dev Umgebung (Release und Debug-Modus) die Anwendung funktioniert gut, aber wenn ich es auf meinem Server veröffentlichen bekomme ich diese Ausnahme von einer der Dateien:

SqlDbType.SmallDateTime Überlauf. Wert '12/31/1899 00:00:00 'ist aus der Reichweite. Muss zwischen 01.01.1900, 12:00:00 Uhr und 06.06.2079, 11:59:59 Uhr, PM sein .;

Die Anwendung funktioniert gut, auch wenn ich meine Verbindungszeichenfolge auf die entfernte Datenbank in VS.

Hat jemand schon einmal auf dieses Problem gestoßen? Irgendwelche Ideen, wie man es repariert oder verschiedene Tests durchführt, um herauszufinden, wo das Problem liegt?

Vollständige Ausnahme

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) 

Vielen Dank im Voraus!

Aktualisierung !!! Gefunden das Feld, das Problem hat

Ich extrahierte in CSV-Datei die Charge, die Problem hat, um das falsche Datum zu finden.

Die ursprüngliche Datei kommt mit Wert 01.01.1900 aber nach den Behandlungen auf dem Feld (Methode ParseExcelDate oben erwähnt) irgendwie das Feld wird 31.12.1899.

Auch die anderen Datumswerte sind mit Original-Datei passend

ich über zwei mögliche Lösungen gedacht, aber ich nicht noch verstehen, warum dies so war ich zufällig auf Festsetzung noch nicht zufrieden bin. Irgendwelche Ideen?

+0

Haben Sie Ihre Variablenwerte überprüft, wenn dieser Fehler auftritt? – Shnugo

+0

Können Sie erfassen, welche Zeile nach dem Veröffentlichen den Fehler auslöst (empfohlen mit try ... catch block und vollständige Fehlermeldung in der benutzerdefinierten Fehlerseite anzeigen)? Welche Art von Excel-Daten löst eine Ausnahme aus? Fügen Sie ggf. eine Fehler-Stack-Verfolgung ein. –

+0

Entschuldigung für die verzögerte Antwort. Die Datei, an der ich arbeite, hat 42k Zeilen, ich habe es geschafft, den Batch von 1k Zeilen, der das Problem hatte, in CSV zu extrahieren, aber alle smalldatetime Spalten (nur 2) sind ok, und nur ein Wert wird als initiiert 1900-01-01, einige sind als "Null" gesetzt, die ich auf den Standardwert von 1900 umwandele ... * Aber etwas ist mir aufgefallen, die CSV-Datei ist in einigen Feldern nicht in Ordnung, ich meine, die Spalten verschoben was möglicherweise die Quelle des Problems ist, oder es könnte nur der Code sein, um Datatable in CSV zu konvertieren, der falsch ist. –

Antwort

0

Beim Analysieren von Werten aus Excel mit OpenXML SDK werden Datumsangaben als Gleitkommazahlen (dh 45231,4221) ausgegeben. Da der Feldwert 1900-01-01 = 1,0 war, wurde .NET in seinen eigenen Standardwert konvertiert, der 1899-12-30 = 1,0 ist.

Um es zu beheben ich eine weitere Bedingung zum ersten gemacht if-Anweisung in der Methode „ParseExcelDate“

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); 
... 

Dieser Beitrag hat mir geholfen, zu dieser Lösung zu erhalten: What is equivalent of DateTime.ToOADate() in javascript?

Aber ich immer noch don‘ t wissen, wie es auf meinem lokalen Rechner funktionierte, aber nicht auf dem Server