Получено недопустимое значение длины столбца от клиента bcp для colid 6


Я хочу массово загружать данные csv-файла в sql server 2005 из кода c#, но я сталкиваюсь с ошибкой ниже -

получил недопустимую длину столбца от клиента bcp для colid 6.

при массовом копировании запись на сервер баз данных

5   51   2012-05-04 08:22:54

5 ответов:

один из столбцов данных в excel (идентификатор столбца 6) имеет один или несколько данных ячейки, которые превышают длину типа данных datacolumn в базе данных.

проверьте данные в excel. Также проверьте данные в excel на соответствие их формата схеме таблицы базы данных.

чтобы избежать этого, попробуйте превысить длину строки типа данных в таблице базы данных.

надеюсь, что это помогает.

Я знаю, что этот пост старый, но я столкнулся с этой же проблемой и наконец нашел решение, чтобы определить, какой столбец был причиной проблемы и доложить по мере необходимости. Я, наконец, понял, что colid который возвращается в SqlException не равен нулю, поэтому вам нужно вычесть 1 из него, чтобы получить значение. После этого он используется в качестве индекса ArrayList _sortedColumnMappings экземпляра SqlBulkCopy, а не индекса сопоставлений столбцов, которые были добавлены экземпляр SqlBulkCopy. Одна вещь, чтобы отметить, что SqlBulkCopy остановится на первой ошибке, полученной так что это не может быть единственной проблемой, но по крайней мере помогает понять это.

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

я столкнулся с аналогичной проблемой при передаче строки в таблицу базы данных с помощью опции SQL BulkCopy. Строка, которую я передавал, состояла из 3 символов, тогда как длина столбца назначения была varchar(20). Я попытался обрезать строку перед вставкой в БД с помощью Trim() функция, чтобы проверить, если проблема была вызвана каким-либо пробелом (ведущим и конечным) в строке. После обрезки строки, он работал нормально.

вы можете попробовать text.Trim()

большой кусок кода, спасибо за обмен!

я использовал отражение, чтобы получить фактическое имя DataMemberName для возврата клиенту при ошибке (я использую массовое сохранение в службе WCF). Надеюсь, кто-то еще найдет, как я это сделал полезным.

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

проверьте размер столбцов в таблице, которую вы выполняете массовую вставку / копирование. varchar или другие строковые столбцы могут быть расширены или значение, которое вы вставляете, должно быть обрезано. Порядок столбцов также должен быть таким же, как в таблице.

например, Увеличьте размер столбца varchar с 30 до 50 =>

ALTER TABLE [dbo].[Имя таблицы] ALTER COLUMN [ColumnName] Varchar (50)