2013-01-03 44 views
0

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

+0

尝试从表格中删除约束并删除索引。你可能也想看看BULK INSERT的sql语句。 – Eugene

+0

该文本文件有一些重复的条目,我不想插入这些条目。 –

回答

3

加载所有的数据到一个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"); 

然后你想迭代每一行(假设你的制表符分隔的数据是由回车逐行分隔的rns),并使用.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)好很多 - 但这是一个起点。

+0

该文本文件有一些重复的条目,我不想插入这些条目。那么我怎么能忽略这些条目呢? –

+1

@PuneetPurohit你需要清理你的数据(最好)在加载到'DataTable'之前。有很多方法可以做到这一点。就我个人而言,我会从现有数据创建一个派生的,清理过的集合,并将派生集合加载到'DataTable'中。我们可以看到您的数据样本吗? –

+0

CC_FIPS \t FULL_NAME_ND AN \t Xixerella AN \t维拉 AN \t Sornas AN \t索尔德 AN \t Sispony的 AN \t Segudet AN \t埃尔塔特 AN \t圣利亚洛里亚 AN \t圣琼德卡塞列斯 AN \t圣科洛马 \t Ransol AN AN AN \t普拉茨 \t帕斯底拉卡萨 \t帕尔 AN AN AN 奥尔迪诺\t \t \t Molleres Nagol AN AN AN \t \t里克斯尔 Ribafeta 马斯马斯Alins的 \t AN AN AN Llumeneres \t \t –