【问题标题】:bulk insertion in MS SQL from a text file从文本文件批量插入 MS SQL
【发布时间】:2013-01-03 09:22:36
【问题描述】:

我有一个包含大约 21 个 lac 条目的文本文件,我想将所有这些条目插入一个表中。最初我在 c# 中创建了一个函数,它逐行读取并插入到表中,但这需要太多时间。请提出一种插入这些批量数据的有效方法,并且该文件包含 TAB(4 个空格)作为分隔符。
而且那个文本文件还包含一些重复的条目,我不想插入这些条目。

【问题讨论】:

  • 尝试从表中删除约束并删除索引。您可能还想查看 BULK INSERT sql 语句。
  • 那个文本文件有一些重复的条目,我不想插入这些条目。

标签: asp.net sql-server c#-4.0 insert database


【解决方案1】:

将所有数据加载到DataTable 对象中,然后使用SqlBulkCopy 批量插入它们:

DataTable dtData = new DataTable("Data");

// load your data here

using (SqlConnection dbConn = new SqlConnection("db conn string"))
{
    dbConn.Open();

    using (SqlTransaction dbTrans = dbConn.BeginTransaction())
    {
        try
        {
            using (SqlBulkCopy dbBulkCopy = new SqlBulkCopy(dbConn, SqlBulkCopyOptions.Default, dbTrans))
            {
                dbBulkCopy.DestinationTableName = "intended SQL table name";
                dbBulkCopy.WriteToServer(dtData );
            }

            dbTrans.Commit();
        }
        catch
        {
            dbTrans.Rollback();
            throw;
        }
    }

    dbConn.Close();
}

我已经包含了将其包装到SqlTransaction 中的示例,因此如果在此过程中出现故障,将会完全回滚。为了让您开始,here's a good CodeProject article 将分隔数据加载到 DataSet 对象中。

在加载前清理数据

好的,我认为您的数据如下所示:

CC_FIPS    FULL_NAME_ND 
AN         Xixerella
AN         Vila 
AN         Sornas
AN         Soldeu
AN         Sispony
... (cut down for brevity)

在这种情况下,您希望像这样创建DataTable:

DataTable dtData = new DataTable("Data");
dtData.Columns.Add("CC_FIPS");
dtData.Columns.Add("FULL_NAME_ND");

然后您要迭代每一行(假设您的制表符分隔的数据由回车逐行分隔)并使用.Select 方法检查此数据是否已存在于DataTable 中,以及是否存在匹配(我正在检查两个值,是否要执行其他操作取决于您)然后不要添加它,从而防止重复。

using (FileStream fs = new FileStream("path to your file", FileMode.Open, FileAccess.Read))
{
    int rowIndex = 0;
    using (StreamReader sr = new StreamReader(fs))
    {
        string line = string.Empty;
        while (!sr.EndOfStream)
        {
            line = sr.ReadLine();

            // use a row index to skip the header row as you don't want to insert CC_FIPS and FULL_NAME_ND
            if (rowIndex > 0)
            {
                // split your data up into a 2-d array tab delimited
                string[] parts = line.Split('\t');

                // now check whether this data has already been added to the datatable
                DataRow[] rows = dtData.Select("CC_FIPS = '" + parts[0] + "' and FULL_NAME_ND = '" + parts[1] + "'");
                if (rows.Length == 0)
                {
                    // if there're no rows, then the data doesn't exist so add it
                    DataRow nr = dtData.NewRow();
                    nr["CC_FIPS"] = parts[0];
                    nr["FULL_NAME_ND"] = parts[1];
                    dtData.Rows.Add(nr);
                }
            }

            rowIndex++;
        }
    }
}

最后,您应该有一个经过消毒的DataTable,您可以将其批量插入。请注意,此代码未经测试,但它是您应该如何做的最佳猜测。有很多方法可以做到这一点,并且可能比这种方法(特别是 LINQ)要好得多 - 但这是一个起点。

【讨论】:

  • 那个文本文件有一些重复的条目,我不想插入这些条目。那么我怎么能忽略这些条目呢?
  • @PuneetPurohit 在加载到DataTable 之前,您需要(最好)清理您的数据。有很多方法可以做到这一点。就我个人而言,我会根据您现有的数据创建一个派生的、经过清理的集,并将派生集加载到 DataTable 中。我们可以查看您的数据样本吗?
  • CC_FIPS FULL_NAME_ND AN Xixerella AN Vila AN Sornas AN Soldeu AN Sispony AN Segudet AN El Tarter AN Sant Julia de Loria AN Sant Joan de Caselles AN Santa Coloma AN Ransol AN Prats AN Pas de la Casa AN Pal AN Ordino AN Nagol AN Molleres AN Meritxell AN Mas de Ribafeta AN Mas d'Alins AN Llumeneres AN Llorts
  • 这些是示例数据..对不起,我不允许显示实际数据,此数据包含国家代码和城市名称
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-01-31
  • 1970-01-01
  • 2013-01-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-07
相关资源
最近更新 更多