Jag vet att det här inlägget är gammalt men jag stötte på samma problem och kom till slut på en lösning för att avgöra vilken kolumn som orsakade problemet och rapportera tillbaka det vid behov. Jag fastställde att colid
returneras i SqlException är inte nollbaserat så du måste subtrahera 1 från det för att få värdet. Efter det används det som index för _sortedColumnMappings
ArrayList för SqlBulkCopy-instansen inte indexet för kolumnmappningarna som lades till i SqlBulkCopy-instansen. En sak att notera är att SqlBulkCopy kommer att sluta vid det första felet som tas emot så detta kanske inte är det enda problemet men åtminstone hjälper till att reda ut det.
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;
}