Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Ungültige Spaltenlänge vom bcp-Client für Colid 6 erhalten

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 es bei Bedarf zu melden. Ich habe festgestellt, dass colid die in der SqlException zurückgegeben wird, ist nicht nullbasiert, daher müssen Sie 1 davon subtrahieren, um den Wert zu erhalten. Danach wird es als Index der _sortedColumnMappings verwendet ArrayList der SqlBulkCopy-Instanz, nicht der Index der Spaltenzuordnungen, die der SqlBulkCopy-Instanz hinzugefügt wurden. Beachten Sie, dass SqlBulkCopy beim ersten empfangenen Fehler anhält, sodass dies möglicherweise nicht das einzige Problem ist, aber zumindest hilft, 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;
}