在SQL Server 中插入一条数据使用Insert语句,但是如果想要批量插入一堆数据的话,循环使用Insert不仅效率低,而且会导致SQL一系统性能问题。下面介绍SQL Server支持的两种批量数据插入方法:Bulk和表值参数(Table-Valued Parameters),高效插入数据。

新建数据库:

--Create DataBase  create database BulkTestDB;  go  use BulkTestDB;  go  --Create Table  Create table BulkTestTable(  Id int primary key,  UserName nvarchar(32),  Pwd varchar(16))  go 
        //使用简单的Insert方法一条条插入 [慢]        #region [ simpleInsert ]        static void simpleInsert()        {            Console.WriteLine("使用简单的Insert方法一条条插入");            Stopwatch sw = new Stopwatch();            SqlConnection sqlconn = new SqlConnection("server=.;database=BulkTestDB;user=sa;password=123456;");            SqlCommand sqlcmd = new SqlCommand();            sqlcmd.CommandText = string.Format("insert into BulkTestTable(Id,UserName,Pwd)values(@p0,@p1,@p2)");            sqlcmd.Parameters.Add("@p0", SqlDbType.Int);            sqlcmd.Parameters.Add("@p1", SqlDbType.NVarChar);            sqlcmd.Parameters.Add("@p2", SqlDbType.NVarChar);            sqlcmd.CommandType = CommandType.Text;            sqlcmd.Connection = sqlconn;            sqlconn.Open();            try            {                //循环插入1000条数据,每次插入100条,插入10次。                  for (int multiply = 0; multiply < 10; multiply++)                {                    for (int count = multiply * 100; count < (multiply + 1) * 100; count++)                    {                         sqlcmd.Parameters["@p0"].Value = count;                        sqlcmd.Parameters["@p1"].Value = string.Format("User-{0}", count * multiply);                        sqlcmd.Parameters["@p2"].Value = string.Format("Pwd-{0}", count * multiply);                        sw.Start();                        sqlcmd.ExecuteNonQuery();                        sw.Stop();                    }                    //每插入10万条数据后,显示此次插入所用时间                      Console.WriteLine(string.Format("Elapsed Time is {0} Milliseconds", sw.ElapsedMilliseconds));                }                Console.ReadKey();            }            catch (Exception ex)            {                Console.WriteLine(ex.Message);            }        }        #endregion

二.较快速的Bulk插入方式:

使用使用Bulk插入[ 较快 ]

        //使用Bulk插入的情况 [ 较快 ]        #region [ 使用Bulk插入的情况 ]        static void BulkToDB(DataTable dt)        {            Stopwatch sw = new Stopwatch();            SqlConnection sqlconn = new SqlConnection("server=.;database=BulkTestDB;user=sa;password=123456;");            SqlBulkCopy bulkCopy = new SqlBulkCopy(sqlconn);            bulkCopy.DestinationTableName = "BulkTestTable";            bulkCopy.BatchSize = dt.Rows.Count;            try            {                sqlconn.Open();                if (dt != null && dt.Rows.Count != 0)                {                    bulkCopy.WriteToServer(dt);                }            }            catch (Exception ex)            {                Console.WriteLine(ex.Message);            }            finally            {                sqlconn.Close();                if (bulkCopy != null)                {                    bulkCopy.Close();                }            }        }        static DataTable GetTableSchema()        {            DataTable dt = new DataTable();            dt.Columns.AddRange(new DataColumn[] {                 new DataColumn("Id",typeof(int)),                new DataColumn("UserName",typeof(string)),                new DataColumn("Pwd",typeof(string))            });            return dt;        }        static void BulkInsert()        {            Console.WriteLine("使用简单的Bulk插入的情况");            Stopwatch sw = new Stopwatch();            for (int multiply = 0; multiply < 10; multiply++)            {                DataTable dt = GetTableSchema();                for (int count = multiply * 100; count < (multiply + 1) * 100; count++)                {                    DataRow r = dt.NewRow();                    r[0] = count;                    r[1] = string.Format("User-{0}", count * multiply);                    r[2] = string.Format("Pwd-{0}", count * multiply);                    dt.Rows.Add(r);                }                sw.Start();                BulkToDB(dt);                sw.Stop();                Console.WriteLine(string.Format("Elapsed Time is {0} Milliseconds", sw.ElapsedMilliseconds));            }        }        #endregion

三.使用简称TVPs插入数据

打开sqlserrver,执行以下脚本:

--Create Table Valued  CREATE TYPE BulkUdt AS TABLE    (Id int,     UserName nvarchar(32),     Pwd varchar(16))  

使用简称TVPs插入数据

        //使用简称TVPs插入数据 [最快]        #region [ 使用简称TVPs插入数据 ]        static void TbaleValuedToDB(DataTable dt)        {            Stopwatch sw = new Stopwatch();            SqlConnection sqlconn = new SqlConnection("server=.;database=BulkTestDB;user=sa;password=123456;");            const string TSqlStatement =                  "insert into BulkTestTable (Id,UserName,Pwd)" +                  " SELECT nc.Id, nc.UserName,nc.Pwd" +                  " FROM @NewBulkTestTvp AS nc";            SqlCommand cmd = new SqlCommand(TSqlStatement, sqlconn);            SqlParameter catParam = cmd.Parameters.AddWithValue("@NewBulkTestTvp", dt);            catParam.SqlDbType = SqlDbType.Structured;            catParam.TypeName = "dbo.BulkUdt";            try            {                sqlconn.Open();                if (dt != null && dt.Rows.Count != 0)                {                    cmd.ExecuteNonQuery();                }            }            catch (Exception ex)            {                Console.WriteLine("error>" + ex.Message);            }            finally            {                sqlconn.Close();            }        }        static void TVPsInsert()        {            Console.WriteLine("使用简称TVPs插入数据");            Stopwatch sw = new Stopwatch();            for (int multiply = 0; multiply < 10; multiply++)            {                DataTable dt = GetTableSchema();                for (int count = multiply * 100; count < (multiply + 1) * 100; count++)                {                    DataRow r = dt.NewRow();                    r[0] = count;                    r[1] = string.Format("User-{0}", count * multiply);                    r[2] = string.Format("Pwd-{0}", count * multiply);                    dt.Rows.Add(r);                }                sw.Start();                TbaleValuedToDB(dt);                sw.Stop();                Console.WriteLine(string.Format("Elapsed Time is {0} Milliseconds", sw.ElapsedMilliseconds));            }            Console.ReadLine();          }        #endregion

更多相关文章

  1. MySQL系列多表连接查询92及99语法示例详解教程
  2. Android(安卓)- Manifest 文件 详解
  3. Android的Handler机制详解3_Looper.looper()不会卡死主线程
  4. Selector、shape详解(一)
  5. android2.2资源文件详解4--menu文件夹下的菜单定义
  6. Android发送短信方法实例详解
  7. Android(安卓)读取资源文件实例详解
  8. 详解Android中的屏幕方向
  9. Android学习笔记(10)————Android的Listview详解1(ArrayAdapte

随机推荐

  1. 感情 | 小鹿的大学恋爱史
  2. Java语言程序设计(五)从对话框获取输入及St
  3. Java中级进阶之集合框架比较
  4. 入门|你所不知道编程入门的重要性
  5. Java语言程序设计(六)对话框应用实例及随机
  6. 方向 | 2018 选择 Android 还是 Python?
  7. Java中级进阶之IO流
  8. 学习
  9. linux切换php版本--centos7配置
  10. 入职以来,我和老大之间的故事。