it-swarm.com.de

Es wurde eine ungültige Spaltenlänge vom bcp-Client für Spalte 6 empfangen

Ich möchte CSV-Dateidaten von C # -Code auf SQL Server 2005 hochladen, es tritt jedoch der folgende Fehler auf:

Es wurde eine ungültige Spaltenlänge vom bcp-Client für Spalte 6 empfangen.

bei Massenkopien auf den Datenbankserver schreiben

70
Sana Sana

Eine der Datenspalten in Excel (Spalten-ID 6) enthält eine oder mehrere Zellendaten, die die Datenspalten-Datentyplänge in der Datenbank überschreiten.

Überprüfen Sie die Daten in Excel. Überprüfen Sie auch, ob die Daten in Excel in ihrem Format mit dem Datenbanktabellenschema übereinstimmen.

Um dies zu vermeiden, versuchen Sie, die Datenlänge des String-Datentyps in der Datenbanktabelle zu überschreiten.

Hoffe das hilft.

57
Dinesh

Ich weiß, dass dieser Beitrag alt ist, aber ich bin auf dasselbe Problem gestoßen und habe schließlich eine Lösung gefunden, um festzustellen, welche Spalte das Problem verursacht hat, und habe es bei Bedarf zurückgemeldet. Das habe ich festgestellt colid Rückgabe in der SqlException ist nicht nullbasiert, daher müssen Sie 1 davon subtrahieren, um den Wert zu erhalten. Danach wird es als Index des _sortedColumnMappings ArrayList der SqlBulkCopy-Instanz, nicht der Index der Spaltenzuordnungen, die der SqlBulkCopy-Instanz hinzugefügt wurden. Zu beachten ist, dass SqlBulkCopy beim ersten empfangenen Fehler stoppt. Dies ist möglicherweise nicht das einzige Problem, hilft jedoch, es herauszufinden.

try
{
    bulkCopy.WriteToServer(importTable);
    sqlTran.Commit();
}    
catch (SqlException ex)
{
    if (ex.Message.Contains("Received an invalid column length from the bcp client for colid"))
    {
        string pattern = @"\d+";
        Match match = Regex.Match(ex.Message.ToString(), pattern);
        var index = Convert.ToInt32(match.Value) -1;

        FieldInfo fi = typeof(SqlBulkCopy).GetField("_sortedColumnMappings", BindingFlags.NonPublic | BindingFlags.Instance);
        var sortedColumns = fi.GetValue(bulkCopy);
        var items = (Object[])sortedColumns.GetType().GetField("_items", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(sortedColumns);

        FieldInfo itemdata = items[index].GetType().GetField("_metadata", BindingFlags.NonPublic | BindingFlags.Instance);
        var metadata = itemdata.GetValue(items[index]);

        var column = metadata.GetType().GetField("column", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).GetValue(metadata);
        var length = metadata.GetType().GetField("length", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).GetValue(metadata);
        throw new DataFormatException(String.Format("Column: {0} contains data with a length greater than: {1}", column, length));
    }

    throw;
}
157
b_stil

Überprüfen Sie die Größe der Spalten in der Tabelle, die Sie als Masseneinfügung/-kopie ausführen. Möglicherweise müssen die Spalten varchar oder andere Zeichenfolgen erweitert werden, oder der Wert, den Sie einfügen, muss abgeschnitten werden. Die Spaltenreihenfolge sollte auch mit der in der Tabelle übereinstimmen.

z. B. Erhöhen Sie die Größe der varchar-Spalte 30 auf 50 =>

ALTER TABLE [dbo]. [TableName] ALTER COLUMN [ColumnName] Varchar (50)

1

Bei der Übergabe einer Zeichenfolge an die Datenbanktabelle mit der Option SQL BulkCopy trat ein ähnliches Problem auf. Die Zeichenfolge, die ich übergeben habe, bestand aus 3 Zeichen, während die Länge der Zielspalte varchar(20) war. Ich habe versucht, die Zeichenfolge zu trimmen, bevor ich sie mit der Funktion Trim() in die Datenbank einfügte, um zu überprüfen, ob das Problem auf Leerzeichen (vor und nach) in der Zeichenfolge zurückzuführen ist. Nach dem Trimmen der Zeichenfolge hat es gut funktioniert.

Sie können text.Trim() versuchen

1
Liji Chandran

Toller Code, danke fürs Teilen!

Am Ende habe ich Reflection verwendet, um den tatsächlichen DataMemberName zu erhalten, der bei einem Fehler an einen Client zurückgegeben wird (ich verwende Bulk Save in einem WCF-Dienst). Hoffentlich findet jemand anderes, wie ich es getan habe, nützlich.

static string GetDataMemberName(string colName, object t) {
  foreach(PropertyInfo propertyInfo in t.GetType().GetProperties()) {
    if (propertyInfo.CanRead) {
      if (propertyInfo.Name == colName) {
        var attributes = propertyInfo.GetCustomAttributes(typeof(DataMemberAttribute), false).FirstOrDefault() as DataMemberAttribute;
        if (attributes != null && !string.IsNullOrEmpty(attributes.Name))
          return attributes.Name;
        return colName;
      }
    }
  }
  return colName;
}
0
infocyde