将CSV文件上传到SQL Server

use*_*221 25 .net c# sql-server csv

csv使用C#将大型数据文件上传到SQL Server 的最佳方法是什么?该文件包含大约30,000行和25列.

Kir*_*irk 50

第一关,你不需要编程.您可以使用SQL管理工具将CSV文件直接上载到SQL数据库中.但是,如果您真的需要通过编程来完成,请阅读以下内容.

就个人而言,我认为这种方法是通过编程实现最有效,最简单的方法.

通常,您可以分两步完成

第1步是读取CSV文件,并保存记录作为DataTable.
第二步骤是存储检索DataTable到SQL数据库表作为本体条目

这是一个返回CSV文件数据的函数DataTable.调用并将其保存在内存中,您可以随心所欲地执行任何操作.

此函数将CSV读取文件返回到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;
    }
  }
Run Code Online (Sandbox Code Playgroud)

SQLBulkCopy - 使用此函数将Retrieved DataTable插入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);
         }
     }
Run Code Online (Sandbox Code Playgroud)

资源

  • 应该注意的是,这甚至会在将文件上传到服务器之前将整个文件读入计算机的内存中.如果要上传大量文件,这可能是一个问题.一种更好的方法可能是为文件块创建一个行数组,并调用public'void WriteToServer(DataRow [] rows)'重载. (5认同)
  • 如果您看到“Microsoft.VisualBasic.FileIO 不存在”,请单击 [此链接](http://stackoverflow.com/a/17146200/283650)。 (2认同)

Raj*_*ajN 5

这是另一种通过编程将CSV上传到数据库的方法。Cinchoo ETL是一个开源库,可以使用 DataReader 将 CSV 文件上传到数据库,这是一种流式方法,几乎​​没有内存开销。

这是如何做到这一点的示例

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());
    }
}
Run Code Online (Sandbox Code Playgroud)


Mic*_*ski 5

我发现将大型 CSV 文件导入 SQL Server 的最佳方法是使用SqlBulkCopyIDataReader实现。这样做的好处是,您不必将整个文件读入内存(使用 DataTable 方法就是这种情况),并且您可以控制发送到 SQL Server 的批处理的大小。它的缺点是你必须实现IDataReader我见过的最长的 MS 接口之一。

我写了一个 nuget 包来满足你的需要。它使用很棒的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);
Run Code Online (Sandbox Code Playgroud)

还有针对更复杂场景的附加配置选项(灵活的列映射、csv 文件中不存在的附加静态列值、值转换)。如果您感兴趣,该项目位于Github上,并以nuget 包的形式提供。

作为参考,以下是如何使用SqlBulkCopywith 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();
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)