it-roy-ru.com

Загрузить файл CSV на сервер SQL

Каков наилучший способ загрузить большой файл данных csv на сервер SQL с помощью C #? Файл содержит около 30000 строк и 25 столбцов. 

22
user3083221

Во-первых, вам не нужно программировать вещи. Вы можете напрямую загружать файлы CSV в базу данных SQL с помощью инструментов управления SQL. Однако, если вам действительно нужно сделать это с помощью программирования, просто прочитайте ниже.

Лично я считаю, что такой подход является наиболее эффективным и простым способом программирования.

В общем, вы можете достичь этого в два этапа

1st шаг - прочитать файл CSV и сохранить записи как DataTable.
2nd шаг - сохранить извлеченную DataTable в таблицу базы данных SQL в виде массовой записи

Эта функция возвращает данные файла CSV как переменную DataTable. Позвони и сохрани в памяти, и ты сможешь делать с ней все, что захочешь.

Эта функция возвращает файл CSV Read в DataTable. 

private static DataTable GetDataTabletFromCSVFile(string csv_file_path)
    {
        DataTable csvData = new DataTable();
        try
        {
          using(TextFieldParser csvReader = new TextFieldParser(csv_file_path))
             {
                csvReader.SetDelimiters(new string[] { "," });
                csvReader.HasFieldsEnclosedInQuotes = true;
                string[] colFields = csvReader.ReadFields();
                foreach (string column in colFields)
                {
                    DataColumn datecolumn = new DataColumn(column);
                    datecolumn.AllowDBNull = true;
                    csvData.Columns.Add(datecolumn);
                }
                while (!csvReader.EndOfData)
                {
                    string[] fieldData = csvReader.ReadFields();
                    //Making empty value as null
                    for (int i = 0; i < fieldData.Length; i++)
                    {
                        if (fieldData[i] == "")
                        {
                            fieldData[i] = null;
                        }
                    }
                    csvData.Rows.Add(fieldData);
                }
            }
        }
        catch (Exception ex)
        {
           return null;
        }
        return csvData;
    }
  }

SQLBulkCopy - используйте эту функцию для вставки извлеченной таблицы данных в таблицу Sql.

static void InsertDataIntoSQLServerUsingSQLBulkCopy(DataTable csvFileData)
{
    using(SqlConnection dbConnection = new SqlConnection("Data Source=ProductHost;Initial Catalog=yourDB;Integrated Security=SSPI;"))
    {
         dbConnection.Open();
         using (SqlBulkCopy s = new SqlBulkCopy(dbConnection))
         {
             s.DestinationTableName = "Your table name";
             foreach (var column in csvFileData.Columns)
             s.ColumnMappings.Add(column.ToString(), column.ToString());
             s.WriteToServer(csvFileData);
         }
     }

Источник

43
Kirk

Вот еще один способ загрузки CSV в базу данных с помощью программирования. Cinchoo ETL , библиотека с открытым исходным кодом может выполнять загрузку CSV-файла в базу данных с использованием DataReader, что является потоковым подходом с минимальными или нулевыми накладными расходами памяти. 

Вот пример, как это сделать

string connectionstring = @"#YOUR DB ConnectionString#";
using (SqlBulkCopy bcp = new SqlBulkCopy(connectionstring))
{
    using (var p = new ChoCSVReader("#YOUR CSV FILE#").WithFirstLineHeader())
    {
        bcp.DestinationTableName = "#TABLENAME#";
        bcp.EnableStreaming = true;
        bcp.BatchSize = 10000;
        bcp.BulkCopyTimeout = 0;
        bcp.NotifyAfter = 100;
        bcp.SqlRowsCopied += delegate (object sender, SqlRowsCopiedEventArgs e)
        {
            Console.WriteLine(e.RowsCopied.ToString("#,##0") + " rows copied.");
        };
        bcp.WriteToServer(p.AsDataReader());
    }
}
3
RajN

Лучший способ импортировать большие файлы CSV в SQL Server - использовать SqlBulkCopy вместе с реализацией IDataReader. Хорошая вещь в том, что вы не читаете весь файл в память (как в случае с подходом DataTable), и вы можете контролировать размер пакета, который отправляется на SQL Server. Плохая вещь в том, что вы должны реализовать IDataReader, который является одним из самых длинных интерфейсов MS, которые я видел.

Я написал пакет Nuget, который поможет вам. Он использует пакет awesome CsvHelper , поэтому требуется очень мало настроек. Самый простой сценарий будет выглядеть так:

//Instantiate the reader, providing the list of columns which matches 1 to 1 the data table structure.
var dataReader = new CsvDataReader(filePath,
    new List<TypeCode>(5)
    {
        TypeCode.String,
        TypeCode.Decimal,
        TypeCode.String,
        TypeCode.Boolean,
        TypeCode.DateTime
    });

bulkCopyUtility.BulkCopy("TableName", dataReader);

Есть также дополнительные параметры конфигурации для более сложных сценариев (гибкое сопоставление столбцов, дополнительные статические значения столбцов, которых нет в файле csv, преобразование значений) . Если вам интересно, проект находится на Github и доступен как пакет nuget .

Для справки, вот как использовать SqlBulkCopy с IDataReader:

public void BulkCopy(string tableName, IDataReader dataReader, Action<SqlBulkCopy>  configureSqlBulkCopy)
{
    using (SqlConnection dbConnection = new SqlConnection(connectionString))
    {
        dbConnection.Open();

        using (SqlBulkCopy bulkCopy = new SqlBulkCopy(dbConnection))
        {
            bulkCopy.BatchSize = 3000; //Data will be sent to SQL Server in batches of this size
            bulkCopy.EnableStreaming = true;
            bulkCopy.DestinationTableName = tableName;

            //This will ensure mapping based on names rather than column position
            foreach (DataColumn column in dataReader.GetSchemaTable().Columns)
            {
                bulkCopy.ColumnMappings.Add(column.ColumnName, column.ColumnName);
            }

            //If additional, custom configuration is required, invoke the action
            configureSqlBulkCopy?.Invoke(bulkCopy);

            try
            {
                // Write from the source to the destination.
                bulkCopy.WriteToServer(dataReader);
            }
            finally
            {
                dataReader.Close();
            }
        }
    }
}
3
Michal Ciesielski

Это звучит как идеальная работа для SSIS. Это бесплатная часть SQL Server, она может перебирать все CSV-файлы в папке, очень быстрая и имеет отличную обработку ошибок и ведение журнала.

1
benjamin moskovits

Этот метод использует функцию SQLBulkCopy (), но не считывает весь файл в память.

Хитрость в том, что он реализует класс IDataReader для чтения файла .csv.

https://www.codeproject.com/Tips/1029831/Fast-and-Simple-IDataReader-Implementation-to-Read

1
Michael Potter

Используйте System.Data.SqlClient.SqlBulkCopy class для вставки данных в таблицы Sql. Чтобы использовать этот класс, вам также необходимо преобразовать данные CVS в DataTable, см. здесь один из способов.

1
pakeha_by

Вы также можете использовать Bulk Insert

Public Shared Function bulkQuery()

        Dim query As StringBuilder = New StringBuilder

        query.Append("USE Import_DB BULK INSERT dbo.[Insert_Table] FROM")
        query.Append(" 'C:\Insert_Table.csv' ")
        query.Append("With (FIELDTERMINATOR = ',', ROWTERMINATOR = '\n')")

        Return query.ToString

    End Function

Будьте внимательны, хотя, поскольку имя таблицы и имя csv должны быть идентичны, а количество столбцов в csv должно быть таким же, как в предварительно определенной таблице.

0
ruedi