如何将CSV导入到SqlServer 中?

咨询区

  • user3083221

请问在 C# 中是否有好的方式实现将一个大的 csv 导入到 SQL Server 中,这个 csv 文件包含大概 30000 行,25 列。.

回答区

  • Kirk

其实你不需要通过编程的方式,完全可以用 SQL Server 管理器界面 直接将 CSV 导入到 SQL Server 中,如果你真的想要编程实现的话,也不是没有办法,大概步骤如下:

  1. 将 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;
    }
}

  1. 通过 SQLBulkCopy 将 DataTable 插入到 Table 中

对于 Sql Server 的批量插入,绝对首选 SqlBulkCopy ,参考如下代码:

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

  • Cinchoo

有一个开源工具包:ChoETL (https://www.nuget.org/packages/ChoETL/) 也可以实现通过编程的方式实现批量导入,它是一种流式操作,只需要很少甚至不需要内存,参考如下代码:

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

点评区

在现实开发中,这种需求还是蛮常见的,学习了。