2012-05-04 17 views

Respuesta

47

una de las columnas de datos en el excel (columna Id 6) tiene una o más de datos celular que exceda la longitud DataColumn tipo de datos en la base de datos.

Verificar los datos en excel. También verifique los datos en Excel para que su formato cumpla con el esquema de la tabla de la base de datos.

Para evitar esto, intente exceder la longitud de datos del tipo de datos de cadena en la tabla de la base de datos.

Espero que esto ayude.

98

Sé que esta publicación es antigua, pero me encontré con este mismo problema y finalmente descubrí una solución para determinar qué columna causaba el problema y lo informaba cuando era necesario. Finalmente descubrí que el colid que se devuelve en la SqlException no se basa en cero, por lo que necesita restar 1 para obtener el valor. Después de eso, se usa como índice de _sortedColumnMappings ArrayList de la instancia de SqlBulkCopy, no del índice de las asignaciones de columnas que se agregaron a la instancia de SqlBulkCopy. Una cosa a tener en cuenta es que SqlBulkCopy se detendrá en el primer error recibido, por lo que este puede no ser el único problema, pero al menos ayuda a resolverlo.

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; 
}
+2

Esto funciona muy bien, gracias por sumisión. – Steven

+0

¿Sabes si también es posible obtener la fila nr? –

+0

¿De dónde obtiene DataFormatException? ¿Es esta una clase local para tu proyecto? Además, su código se come todas las demás excepciones sql ... tal vez hacer un nuevo lanzamiento? – OmegaMan

0

que enfrentan el mismo tipo de problema al pasar una cadena a la tabla de base de datos utilizando la opción SQL bulkcopy. La cadena que estaba pasando era de 3 caracteres mientras que la longitud de la columna de destino era varchar(20). Intenté recortar la cadena antes de insertar en DB utilizando la función Trim() para verificar si el problema se debió a cualquier espacio (inicial y final) en la cadena. Después de recortar la cadena, funcionó bien.

Usted puede intentar text.Trim()

0

Gran parte de código, gracias por compartir!

Terminé utilizando la reflexión para obtener el DataMemberName real para devolver a un cliente en un error (estoy usando el almacenamiento masivo en un servicio WCF). Con suerte, alguien más encontrará cómo lo hice útil.

static string GetDataMemberName(string colName, object t) { 
 
    foreach(PropertyInfo propertyInfo in t.GetType().GetProperties()) { 
 
    if (propertyInfo.CanRead) { 
 
     if (propertyInfo.Name == colName) { 
 
     var attributes = propertyInfo.GetCustomAttributes(typeof(DataMemberAttribute), false).FirstOrDefault() as DataMemberAttribute; 
 
     if (attributes != null && !string.IsNullOrEmpty(attributes.Name)) 
 
      return attributes.Name; 
 
     return colName; 
 
     } 
 
    } 
 
    } 
 
    return colName; 
 
}

0

comprobar el tamaño de las columnas en la tabla que está haciendo mayor inserción/copia. es posible que sea necesario extender las varchar u otras columnas de cadena o se debe recortar el valor que está insertando. El orden de la columna también debe ser el mismo que en la tabla.

por ejemplo, aumentar el tamaño de la columna varchar 30 a 50 =>

ALTER TABLE [dbo]. [NombreTabla] ALTER COLUMN [ColumnName] Varchar que (50)

Cuestiones relacionadas