日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

SQL Server 批量插入数据的两种方法(转)

發布時間:2025/4/5 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SQL Server 批量插入数据的两种方法(转) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

原文:http://blog.csdn.net/tjvictor/article/details/4360030

????? 在SQL Server 中插入一條數據使用Insert語句,但是如果想要批量插入一堆數據的話,循環使用Insert不僅效率低,而且會導致SQL一系統性能問題。下面介紹 SQL Server支持的兩種批量數據插入方法:Bulk和表值參數(Table-Valued Parameters)。

運行下面的腳本,建立測試數據庫和表值參數。

[c-sharp] view plaincopy
  • --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??
  • --Create?Table?Valued??
  • CREATE?TYPE?BulkUdt?AS?TABLE??
  • ??(Id?int,??
  • ???UserName?nvarchar(32),??
  • ???Pwd?varchar(16))??
  • ?

    下面我們使用最簡單的Insert語句來插入100萬條數據,代碼如下:

    [c-sharp] view plaincopy
  • Stopwatch?sw?=?new?Stopwatch();??
  • ??
  • SqlConnection?sqlConn?=?new?SqlConnection(??
  • ????ConfigurationManager.ConnectionStrings["ConnStr"].ConnectionString);//連接數據庫??
  • ??
  • SqlCommand?sqlComm?=?new?SqlCommand();??
  • sqlComm.CommandText?=?string.Format("insert?into?BulkTestTable(Id,UserName,Pwd)values(@p0,@p1,@p2)");//參數化SQL??
  • sqlComm.Parameters.Add("@p0",?SqlDbType.Int);??
  • sqlComm.Parameters.Add("@p1",?SqlDbType.NVarChar);??
  • sqlComm.Parameters.Add("@p2",?SqlDbType.VarChar);??
  • sqlComm.CommandType?=?CommandType.Text;??
  • sqlComm.Connection?=?sqlConn;??
  • sqlConn.Open();??
  • try??
  • {??
  • ????//循環插入100萬條數據,每次插入10萬條,插入10次。??
  • ????for?(int?multiply?=?0;?multiply?<?10;?multiply++)??
  • ????{??
  • ????????for?(int?count?=?multiply?*?100000;?count?<?(multiply?+?1)?*?100000;?count++)??
  • ????????{??
  • ??
  • ????????????sqlComm.Parameters["@p0"].Value?=?count;??
  • ????????????sqlComm.Parameters["@p1"].Value?=?string.Format("User-{0}",?count?*?multiply);??
  • ????????????sqlComm.Parameters["@p2"].Value?=?string.Format("Pwd-{0}",?count?*?multiply);??
  • ????????????sw.Start();??
  • ????????????sqlComm.ExecuteNonQuery();??
  • ????????????sw.Stop();??
  • ????????}??
  • ????????//每插入10萬條數據后,顯示此次插入所用時間??
  • ????????Console.WriteLine(string.Format("Elapsed?Time?is?{0}?Milliseconds",?sw.ElapsedMilliseconds));??
  • ????}??
  • }??
  • catch?(Exception?ex)??
  • {??
  • ????throw?ex;??
  • }??
  • finally??
  • {??
  • ????sqlConn.Close();??
  • }??
  • ??
  • Console.ReadLine();??
  • 耗時圖如下:

    由于運行過慢,才插入10萬條就耗時72390 milliseconds,所以我就手動強行停止了。

    ?

    下面看一下使用Bulk插入的情況:

    bulk方法主要思想是通過在客戶端把數據都緩存在Table中,然后利用SqlBulkCopy一次性把Table中的數據插入到數據庫

    代碼如下:

    [c-sharp] view plaincopy
  • public?static?void?BulkToDB(DataTable?dt)??
  • {??
  • ????SqlConnection?sqlConn?=?new?SqlConnection(??
  • ????????ConfigurationManager.ConnectionStrings["ConnStr"].ConnectionString);??
  • ????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)??
  • ????{??
  • ????????throw?ex;??
  • ????}??
  • ????finally??
  • ????{??
  • ????????sqlConn.Close();??
  • ????????if?(bulkCopy?!=?null)??
  • ????????????bulkCopy.Close();??
  • ????}??
  • }??
  • ??
  • public?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?Main(string[]?args)??
  • {??
  • ????Stopwatch?sw?=?new?Stopwatch();??
  • ????for?(int?multiply?=?0;?multiply?<?10;?multiply++)??
  • ????{??
  • ????????DataTable?dt?=?Bulk.GetTableSchema();??
  • ????????for?(int?count?=?multiply?*?100000;?count?<?(multiply?+?1)?*?100000;?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();??
  • ????????Bulk.BulkToDB(dt);??
  • ????????sw.Stop();??
  • ????????Console.WriteLine(string.Format("Elapsed?Time?is?{0}?Milliseconds",?sw.ElapsedMilliseconds));??
  • ????}??
  • ??
  • ????Console.ReadLine();??
  • }??
  • 耗時圖如下:

    可見,使用Bulk后,效率和性能明顯上升。使用Insert插入10萬數據耗時72390,而現在使用Bulk插入100萬數據才耗時17583。

    ?

    最后再看看使用表值參數的效率,會另你大為驚訝的。

    ?

    表值參數是SQL Server 2008新特性,簡稱TVPs。對于表值參數不熟悉的朋友,可以參考最新的book online,我也會另外寫一篇關于表值參數的博客,不過此次不對表值參數的概念做過多的介紹。言歸正傳,看代碼:

    [c-sharp] view plaincopy
  • public?static?void?TableValuedToDB(DataTable?dt)??
  • {??
  • ????SqlConnection?sqlConn?=?new?SqlConnection(??
  • ??????ConfigurationManager.ConnectionStrings["ConnStr"].ConnectionString);??
  • ????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;??
  • ????//表值參數的名字叫BulkUdt,在上面的建立測試環境的SQL中有。??
  • ????catParam.TypeName?=?"dbo.BulkUdt";??
  • ????try??
  • ????{??
  • ??????sqlConn.Open();??
  • ??????if?(dt?!=?null?&&?dt.Rows.Count?!=?0)??
  • ??????{??
  • ??????????cmd.ExecuteNonQuery();??
  • ??????}??
  • ????}??
  • ????catch?(Exception?ex)??
  • ????{??
  • ??????throw?ex;??
  • ????}??
  • ????finally??
  • ????{??
  • ??????sqlConn.Close();??
  • ????}??
  • }??
  • ??
  • public?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?Main(string[]?args)??
  • {??
  • ????Stopwatch?sw?=?new?Stopwatch();??
  • ????for?(int?multiply?=?0;?multiply?<?10;?multiply++)??
  • ????{??
  • ????????DataTable?dt?=?TableValued.GetTableSchema();??
  • ????????for?(int?count?=?multiply?*?100000;?count?<?(multiply?+?1)?*?100000;?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();??
  • ????????TableValued.TableValuedToDB(dt);??
  • ????????sw.Stop();??
  • ????????Console.WriteLine(string.Format("Elapsed?Time?is?{0}?Milliseconds",?sw.ElapsedMilliseconds));??
  • ????}??
  • ??
  • ????Console.ReadLine();??
  • }??
  • 耗時圖如下:

    比Bulk還快5秒。

    ?

    如需轉載,請注明此文原創自CSDN TJVictor專欄:http://blog.csdn.net/tjvictor/archive/2009/07/18/4360030.aspx

    轉載于:https://www.cnblogs.com/tonykan/archive/2013/05/25/3098750.html

    《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀

    總結

    以上是生活随笔為你收集整理的SQL Server 批量插入数据的两种方法(转)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。