загрузка csv в БД SQL C#

96
15 октября 2019, 20:10

Необходимо загрузить большой csv файл в БД (1,5 Гб). Пробовал делать построчную запись с помощью INSERT - это очень долго. 100 000 строк загружается примерно 2 минуты. В файле 120 000 000 строк. Прочитал, что можно использовать SQLBulkCopy и это будет в разы быстрее. Но вопрос в том, можно ли сделать загрузку CSV с разбивкой по столбцам? Например у меня в CSV Series и Number столбцы с разделителем ",". Таблица тоже с двумя аналогичными столбцами. Есть какие-нибудь еще более быстрые способы загрузки или как сделать мапинг полей

string line = "";
       string con_str = "server;Database=base;Trusted_Connection=True;";
       using (SqlConnection connection = new SqlConnection(con_str))
       {
            connection.Open();
            using (StreamReader file = new StreamReader(new BufferedStream(File.OpenRead(@"D:\bzip2\WriteLines.csv"), 10 * 1024 * 1024)))
            {
                //string table = "ElmaBadPassport";
                while ((line = file.ReadLine()) != null)
                {   
                    if (line.Length == 11)
                    {   string[] values = line.Split(',');
                        SqlCommand cmd = new SqlCommand("Insert INTO ElmaBadPassport(Series,Number) VALUES (@series, @number)",connection);
                        cmd.Parameters.AddWithValue("@series",values[0].ToString());
                        cmd.Parameters.AddWithValue("@Number", values[1].ToString());
                        cmd.ExecuteNonQuery();
                        //Console.WriteLine(cmd.ExecuteNonQuery());
                    }
                }
            }
            connection.Close();
       }
Answer 1

Для однократного решения задачи я рекомендую использовать ESF Migration ToolKit, который отлично справляется со своей работой в то время, как стандартное средство импорта /экспорта в SSMS делает вставку по 1 записи. Правда минус в том, что он платный...

Если все таки хочется- это самому реализовать, то есть класс SqlBulkCopyColumnMapping, где можно задать маппинг одного поля на другое. Однако, хоть СУБД и пофигу на регистр колонок, однако, BulkCopy не пофиг и он не найдет соответствие схожих имен, но с разным регистром.

А еще, на сколько я знаю, можно прямо из MS SQL через скрипт сделать BULK INSERT:

BULK INSERT SchoolsTemp
    FROM 'C:\CSVData\Schools.csv'
    WITH
    (
    FIRSTROW = 2,
    FIELDTERMINATOR = ',',  --CSV field delimiter
    ROWTERMINATOR = '\n',   --Use to shift the control to next row
    ERRORFILE = 'C:\CSVDATA\SchoolsErrorRows.csv',
    TABLOCK
    )

Правда, не пробовал.

P.S Ну и не забудь в целевой таблице грохнуть всех индексы и ключи, так это тормозит вставку.

READ ALSO
Task.Run - антипаттерн async/await? C#

Task.Run - антипаттерн async/await? C#

Недавно прочитал статью на хабре (upd: из комментов понял, что нужно прицепить цитату, по которой далее вопрос)

90
библиотека PHPExcel

библиотека PHPExcel

Подскажите как сделать дозапись в ексель файл с помощью PHP Excel Те

129
Клавиатура VK API, PHP

Клавиатура VK API, PHP

не могу разобраться с клавиатурой ВКДокументация ВК Как её реализовать? Искал в сети примеры/объяснения так не нашёл для PHP

120
Как выводить данные из бд с условие в php? [закрыт]

Как выводить данные из бд с условие в php? [закрыт]

Как делать с условием я знаю, НО, как сделать чтоб с условием, ну как объяснить Короче вот пример того что мне нужно

121