SQLBULKCOPY бросает систему. Formatexception при запуске writeToserver (datatable)

StackOverflow https://stackoverflow.com/questions/4162155

Вопрос

В настоящее время я пишу метод для чтения данных из файла CSV и импортировать в таблицу SQL.

        DataTable dt = new DataTable();
        String line = null;
        int i = 0;

        while ((line = reader.ReadLine()) != null)
        {
            String[] data = line.Split(',');
            if (data.Length > 0)
            {
                if (i == 0)
                {
                    foreach (object item in data)
                    {
                        DataColumn c = new DataColumn(Convert.ToString(item));
                        if (Convert.ToString(item).Contains("DATE"))
                        {
                            c.DataType = System.Type.GetType("System.DateTime");
                        }
                        else { c.DataType = System.Type.GetType("System.String"); }
                        dt.Columns.Add(c);
                    }
                    i++;
                }
                else
                {
                    DataRow row = dt.NewRow();
                    for (int j = 0; j < data.Length; j++)
                    {
                        if (dt.Columns[j].DataType == System.Type.GetType("System.DateTime"))
                        {
                            row[j] = Convert.ToDateTime(data[j]);
                        }
                        else
                        {
                            row[j] = data[j];
                        }
                    }
                    dt.Rows.Add(row);
                }
            }
        }
        SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings[Constant.CONNECTION_STRING_NAME].ConnectionString);
        SqlBulkCopy s = new SqlBulkCopy(con);
        s.DestinationTableName = "abc";
        con.Open();
        s.WriteToServer(dt);

Проблема при запуске этого метода исключение всегда брошена на S.WRITETOSERVER (DT); говорить

System.formatexception: строка не была распознана как действительное значение dateTime. Есть неизвестное слово, начиная с индекса 0.

Я отлажил и посмотрю, что все данные были загружены в DataTable правильно. Вот пример строки данных в моем файле CSV

DATA_VENDOR_ID,DATA_VENDOR_SUB_ID,DATA_VENDOR_CLIENT_ID,DATA_VENDOR_ACTIVITY_CODE,ACTIVITY_NAME,EFFECTIVE_DATE,ACTIVITY_LEVEL1,ACTIVITY_LEVEL2,ACTIVITY_LEVEL3,ACTIVITY_LEVEL4,ACTIVITY_LEVEL5,PARTICIPANT_ID,DATA_VENDOR_ALT_ID,FILE_CREATION_DATE,INC_VALUE    
V01,,22097,ABCD01,Physical Activity,10/01/2010,Entertain Kiosk,ABCD - EFG 54,30,,AB01,W1234567891,,08/07/2006,100

и моя схема SQL таблицы:

RowID   int Unique/AutoIncrement
DataVendorId    varchar(32) 
DataVendorSubId varchar(32) 
DataVendorClientId  varchar(32) 
DataVendorActivityCode  varchar(32) 
ActivityName    varchar(64) 
EffectiveDate   datetime    
ActivityLevel1  varchar(253)    
ActivityLevel2  varchar(253)    
ActivityLevel3  varchar(253)    
ActivityLevel4  varchar(253)    
ActivityLevel5  varchar(253)    
ParticipantID   varchar(32) 
DataVendorAltId varchar(32) 
FileCreationDate    datetime    
IncValue    varchar(5)  
CreatedDate datetime    optional/allow null
ModifiedDate    datetime    optional/allow null
Это было полезно?

Решение

Первая проблема, которую я вижу, это то, что у вас будут проблемы с RowID столбец; Я ожидаю, что он пытается компенсировать ваши данные одним столбцом на данный момент - это не знает что вы их пропускаете. Вы можете либо беспорядок с отображениями, либо (в вашей таблице данных) добавить RowID Столбец (по индексу 0) - но обратите внимание, что SQL Server будет игнорировать значения, если вы не включаете идентификатор-вставку.

Возможно попробуйте более явное преобразование TateTime:

row[j] = DateTime.ParseExact(data[j], "dd/MM/yyyy", CultureInfo.InvariantCulture);

Обратите внимание, что я не могу сказать из данных, если это DD / мм или мм / дд, поэтому вам может потребоваться настроить это.

Другие советы

У меня была похожая проблема, где были выключены колонны, и как только я определил сопоставление, без проблем:

using (SqlBulkCopy sbc = new SqlBulkCopy(ConfigurationManager.ConnectionStrings["SQLDatabase"].ConnectionString, SqlBulkCopyOptions.KeepIdentity))
            {
                sbc.DestinationTableName = "DestinationTable";
                sbc.ColumnMappings.Add("foo", "bar");
                sbc.ColumnMappings.Add("hello", "world");
                sbc.ColumnMappings.Add("col1", "col2");
                sbc.WriteToServer(data);
            }

Кроме того, у меня есть список для расширения преобразователя DataTable, которое я использую для преобразования моего списка.

public static DataTable ToDataTable<T>(this IEnumerable<T> data)
        {
            PropertyDescriptorCollection properties =
                TypeDescriptor.GetProperties(typeof(T));
            DataTable table = new DataTable();
            foreach (PropertyDescriptor prop in properties)
                table.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType);
            foreach (T item in data)
            {
                DataRow row = table.NewRow();
                foreach (PropertyDescriptor prop in properties)
                    row[prop.Name] = GetDataValue(prop.GetValue(item));
                table.Rows.Add(row);
            }
            return table;
        }

Метод GetDatavalue () очищает мои данные для дат Minvalue и т. Д.:

private static object GetDataValue(object value)
        {
            if (value == null || (value.GetType() == typeof(DateTime) && Convert.ToDateTime(value) == DateTime.MinValue) || (value.GetType() == typeof(DateTime) && Convert.ToDateTime(value) < Convert.ToDateTime("01/01/1753")))
            {
                return DBNull.Value;
            }

            return value;
        }

Поля в вашем файле данных не соответствует таблице, т. Е. Вы пытаетесь вставить DataVendorId в RowId столбец, который вызывает исключение, поскольку вы не можете преобразовать varchar(32) чтобы int.

Переместите столбец вашего удостоверения личности до конца таблицы. Теперь объемная вставка сможет соответствовать всем полям до Это достигает функции идентификации.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top