这几天把sqlserver批量插入也整理了一下,性能方面有很大的提高,下面直接上代码


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Threading;
using System.Web;
using System.Configuration;
using System.Data.SqlClient;
using System.Data;
using System.Diagnostics;
namespace FromSt
{
   public static class Run_From
   {
       private static int dd = 0;
       public static void InsertForTest(object ss)
       {
           InsertData(MakeDT(int.Parse(ss.ToString())));
           //Thread st = new Thread(WriterLog);
           //st.Start();

       }
       public static void WriterLog()
       {
           string ss = DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss") + (dd + 1);
           using (StreamWriter sw = new StreamWriter(@"d:\wService.txt", true, Encoding.GetEncoding("utf-8"), ss.Length))
           {
               sw.WriteLine(ss);
           }

       }
//创建表
       public static DataTable MakeDT(int count)
       {
           DataTable dt = new DataTable();
           //DataColumn dc = new DataColumn ("name1",Type.GetType("System.String"));
           dt.Columns.AddRange(new DataColumn[]{
          new DataColumn("name",Type.GetType("System.String")),
         });
           // dt.Columns.Add(dc);

           Stopwatch sw = new Stopwatch();
           sw.Start();
           for (int i = 0; i < count; i++)
           {
               DataRow dr = dt.NewRow();
               dr["name"] = "zl" + i;
               dt.Rows.Add(dr);
           }
           sw.Stop();
           double dd = sw.Elapsed.TotalSeconds;

           return dt;
       }

       public static void InsertData(DataTable dt)
       {
           string config = ConfigurationManager.ConnectionStrings["Sql2012"].ConnectionString;

           try
           {
               Stopwatch sw = new Stopwatch();
               sw.Start();
               
                   SqlBulkCopy sbc = new SqlBulkCopy(config, SqlBulkCopyOptions.UseInternalTransaction);
                   sbc.BulkCopyTimeout = 500;//超时时间默认30秒钟
                   sbc.SqlRowsCopied += new SqlRowsCopiedEventHandler(OnRowsCopied); //处理完成指定行数后触发的事件;这里不是必须的;
                   sbc.NotifyAfter = dt.Rows.Count; //生成通知事件前要处理的行数
                   sbc.DestinationTableName = "dbo.ss"; //对应数据库的表名
                 
               sw.Stop();
               double dd = sw.Elapsed.TotalSeconds;

           }
           catch (Exception ex)
           {
               throw ex;
           }

       }

    //这里实际是可以不用的,但是为了说明用法,我就写了个方法
       private static void OnRowsCopied(object sender, SqlRowsCopiedEventArgs args)
       {
           string ss = "";
           ss += args.RowsCopied.ToString() + " rows are copied<Br>";
       }
   }
}
-- 下面是逐次向表中插入数据的的用时前面表示的条数后面是秒数;注释中的数据表示表中已有数据
select 1000000/16  -- 0  1个字段
select 1000000/7.90 -- 一百万  一个字段
select 1000000/8.97 -- 二百万  一个字段
select 1000000/7.60 -- 三百万  一个字段
select 1000000/6.54 -- 4百万   一个字段
select 1000000/10.3626133  -- 五百万  两个字段
select 1000000/8.7146654  -- 六百万  两个字段
select 1000000/10.2771326  -- 八百万  两个字段
select 1000000/10.2771326  -- 九百万   两个字段
select 1000000/7.4966066  -- 一千万  两个字段


需要注意下面的事项:

如果在创建表的时候如下面所示,id是自增列有默认值得话,插入式正常的

create(name varchar(50),sex varchar(20),id int identity(1,1)not null);


如果在创建表的时候如下面所示,id是自增列,插入数据不成功(与上面数据结构是相同的,但字段的位置不通)
create(
id int identity(1,1)not null,name varchar(50),sex varchar(20));spacer.gif