Tôi biết bài đăng này đã cũ nhưng tôi đã gặp phải vấn đề tương tự và cuối cùng đã tìm ra giải pháp để xác định cột nào đang gây ra sự cố và báo cáo lại nếu cần. Tôi đã xác định rằng colid
được trả về trong SqlException không dựa trên 0, vì vậy bạn cần phải trừ đi 1 từ nó để nhận giá trị. Sau đó, nó được sử dụng làm chỉ mục của _sortedColumnMappings
ArrayList của cá thể SqlBulkCopy không phải là chỉ mục của ánh xạ cột đã được thêm vào cá thể SqlBulkCopy. Một điều cần lưu ý là SqlBulkCopy sẽ dừng lại ở lỗi đầu tiên nhận được nên đây có thể không phải là vấn đề duy nhất nhưng ít nhất cũng giúp tìm ra nó.
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;
}