C# 将CSV文件上载到SQL server

C# 将CSV文件上载到SQL server,c#,.net,sql-server,csv,C#,.net,Sql Server,Csv,使用C#将大型csv数据文件上载到SQL server的最佳方式是什么?该文件包含大约30000行和25列 使用类将数据插入Sql表。 要使用该类,您还需要将CVS数据转换为DataTable,请参见以下方法之一。首先,您不需要编程。您可以使用SQL管理工具直接将CSV文件上载到SQL数据库中。然而,如果您真的需要通过编程来实现,请阅读下面的内容 我个人认为,通过编程,这种方法是最有效、最简单的方法 通常,您可以通过两个步骤来实现 第一步是读取CSV文件并将记录保存为数据表 第二步是将检索到的D

使用C#将大型
csv
数据文件上载到SQL server的最佳方式是什么?该文件包含大约30000行和25列

使用类将数据插入Sql表。
要使用该类,您还需要将CVS数据转换为DataTable,请参见以下方法之一。

首先,您不需要编程。您可以使用SQL管理工具直接将CSV文件上载到SQL数据库中。然而,如果您真的需要通过编程来实现,请阅读下面的内容

我个人认为,通过编程,这种方法是最有效、最简单的方法

通常,您可以通过两个步骤来实现

第一步是读取CSV文件并将记录保存为数据表

第二步是将检索到的
DataTable
作为批量条目存储到SQL数据库表中

这是一个将CSV文件数据作为
数据表返回的函数。打电话把它记在记忆里,你可以用它做任何你想做的事

此函数将CSV读取文件返回到数据表中。

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

这听起来是SSI的完美工作。它是SQL Server的免费部分,可以循环浏览文件夹中的所有csv文件,速度非常快,具有出色的错误处理和日志记录功能。

此技术使用SQLBulkCopy()功能,但不会将整个文件读入内存

诀窍在于它实现了一个IDataReader类来读取.csv文件


这里是通过编程将CSV上传到数据库的另一种方式,开源库可以使用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());
    }
}

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

我写了一个nuget软件包,可以帮你实现这个功能。它使用了很棒的软件包,所以只需要很少的配置。最简单的场景如下所示:

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

您也可以使用
批量插入

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
但请在此谨慎,因为tablename和csv名称必须相同,csv中的列数必须与预定义表中的列数相同。

private void GetDataTabletFromCSVFile(字符串文件名)
    private void GetDataTabletFromCSVFile(string fileName)
    {
        DataTable dt = new DataTable();
        //dt.TableName = fileName;

        try
        {
            using (TextFieldParser csvReader = new TextFieldParser(fileName))
            {
                csvReader.SetDelimiters(new string[] { "," });
                csvReader.HasFieldsEnclosedInQuotes = true;
                string[] colFields = csvReader.ReadFields();
                //foreach (string column in colFields)
                //{
                //    DataColumn datecolumn = new DataColumn(column);
                //    datecolumn.AllowDBNull = true;
                //    dt.Columns.Add(datecolumn);
                //}
                dt.Columns.AddRange(new DataColumn[8] {
                    new DataColumn("Symbol", typeof(string)),
                new DataColumn("ISIN", typeof(string)),
                new DataColumn("Company", typeof(string)),
                new DataColumn("FirstListingDate", typeof(string)),
                new DataColumn("FaceValue", typeof(string)),
                new DataColumn("PaidUpValue", typeof(string)),
                new DataColumn("MarketLot",typeof(string)),
                new DataColumn("industry",typeof(string))
                });
                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;
                        }
                    }
                    dt.Rows.Add(fieldData);
                }
                var builder = new ConfigurationBuilder()
                    .SetBasePath(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location))
                    .AddJsonFile("appsettings.json");

                var configuration = builder.Build();
                string DBconnection = configuration.GetSection("ConnectionString").Value;
                using (SqlConnection dbConnection = new SqlConnection(DBconnection))
                {
                    dbConnection.Open();
                    using (SqlBulkCopy s = new SqlBulkCopy(dbConnection))
                    {
                        s.DestinationTableName = "Static.dbo.Securitiesinfo";
                        foreach (var column in dt.Columns)
                            s.ColumnMappings.Add(column.ToString(), column.ToString());
                        s.WriteToServer(dt);
                    }
                }

            }
        }
        catch (Exception ex)
        {
            var x = ex;
        }

    }
{ DataTable dt=新的DataTable(); //dt.TableName=文件名; 尝试 { 使用(TextFieldParser csvReader=新的TextFieldParser(文件名)) { SetDelimiters(新字符串[]{“,”}); csvReader.HasFieldsEnclosedInQuotes=true; 字符串[]colFields=csvReader.ReadFields(); //foreach(colFields中的字符串列) //{ //DataColumn datecolumn=新的DataColumn(列); //datecolumn.AllowDBNull=true; //dt.Columns.Add(datecolumn); //} dt.Columns.AddRange(新数据列[8]{ 新数据列(“符号”,类型(字符串)), 新数据列(“ISIN”,类型(字符串)), 新数据列(“公司”,类型(字符串)), 新数据列(“FirstListingDate”,typeof(string)), 新数据列(“FaceValue”,类型(字符串)), 新数据列(“PaidUpValue”,typeof(string)), 新数据列(“MarketLot”,类型(字符串)), 新数据列(“行业”,类型(字符串)) }); 而(!csvReader.EndOfData) { 字符串[]fieldData=csvReader.ReadFields(); //将空值设为null for(int i=0;i
为什么在sql server本身支持导入CSV文件的情况下使用.net上载文件?sql server没有任何将文件上载到的工具-您需要使用其他方法(例如,在IIS上运行的web服务或类似工具)。SQL Server可以从它可以到达的磁盘加载文件-因此,您需要找到一种方法,将该文件放在SQL Server可以读取的位置。要求是,当我们循环并将文件逐个上载到SQL Server时,我们有一个应用程序,所以我需要使用c
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
    private void GetDataTabletFromCSVFile(string fileName)
    {
        DataTable dt = new DataTable();
        //dt.TableName = fileName;

        try
        {
            using (TextFieldParser csvReader = new TextFieldParser(fileName))
            {
                csvReader.SetDelimiters(new string[] { "," });
                csvReader.HasFieldsEnclosedInQuotes = true;
                string[] colFields = csvReader.ReadFields();
                //foreach (string column in colFields)
                //{
                //    DataColumn datecolumn = new DataColumn(column);
                //    datecolumn.AllowDBNull = true;
                //    dt.Columns.Add(datecolumn);
                //}
                dt.Columns.AddRange(new DataColumn[8] {
                    new DataColumn("Symbol", typeof(string)),
                new DataColumn("ISIN", typeof(string)),
                new DataColumn("Company", typeof(string)),
                new DataColumn("FirstListingDate", typeof(string)),
                new DataColumn("FaceValue", typeof(string)),
                new DataColumn("PaidUpValue", typeof(string)),
                new DataColumn("MarketLot",typeof(string)),
                new DataColumn("industry",typeof(string))
                });
                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;
                        }
                    }
                    dt.Rows.Add(fieldData);
                }
                var builder = new ConfigurationBuilder()
                    .SetBasePath(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location))
                    .AddJsonFile("appsettings.json");

                var configuration = builder.Build();
                string DBconnection = configuration.GetSection("ConnectionString").Value;
                using (SqlConnection dbConnection = new SqlConnection(DBconnection))
                {
                    dbConnection.Open();
                    using (SqlBulkCopy s = new SqlBulkCopy(dbConnection))
                    {
                        s.DestinationTableName = "Static.dbo.Securitiesinfo";
                        foreach (var column in dt.Columns)
                            s.ColumnMappings.Add(column.ToString(), column.ToString());
                        s.WriteToServer(dt);
                    }
                }

            }
        }
        catch (Exception ex)
        {
            var x = ex;
        }

    }