So che questo post è vecchio ma mi sono imbattuto in questo stesso problema e alla fine ho trovato una soluzione per determinare quale colonna stava causando il problema e riportarla come necessario. Ho finalmente capito che il colid che viene restituito in SqlException non è a base zero, quindi è necessario sottrarre 1 da esso per ottenere il valore. Dopodiché viene utilizzato come indice della _sortedColumnMappings ArrayList dell'istanza SqlBulkCopy e non dell'indice dei mapping delle colonne che sono stati aggiunti all'istanza SqlBulkCopy. Una cosa da notare è che SqlBulkCopy si fermerà al primo errore ricevuto, quindi questo potrebbe non essere l'unico problema, ma almeno aiuta a capirlo.
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;
}
fonte
2013-10-31 17:02:42
Questo funziona molto bene, grazie per richiedente. – Steven
Sai se è possibile ottenere anche il numero di riga? –
Da dove ricevi DataFormatException? Questa è una classe locale per il tuo progetto? Anche il tuo codice mangia tutte le altre eccezioni sql ... forse fai un rethrow? – OmegaMan