Ik weet dat dit bericht oud is, maar ik kwam hetzelfde probleem tegen en heb uiteindelijk een oplossing bedacht om te bepalen welke kolom het probleem veroorzaakte en indien nodig terug te rapporteren. Ik heb vastgesteld dat colid
geretourneerd in de SqlException is niet gebaseerd op nul, dus u moet er 1 van aftrekken om de waarde te krijgen. Daarna wordt het gebruikt als de index van de _sortedColumnMappings
ArrayList van de SqlBulkCopy-instantie, niet de index van de kolomtoewijzingen die aan de SqlBulkCopy-instantie zijn toegevoegd. Een ding om op te merken is dat SqlBulkCopy stopt bij de eerste ontvangen fout, dus dit is misschien niet het enige probleem, maar het helpt in ieder geval om erachter te komen.
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;
}