SQL Server批量插入數(shù)據(jù)案例詳解
在SQL Server 中插入一條數(shù)據(jù)使用Insert語(yǔ)句,但是如果想要批量插入一堆數(shù)據(jù)的話,循環(huán)使用Insert不僅效率低,而且會(huì)導(dǎo)致SQL一系統(tǒng)性能問題。下面介紹SQL Server支持的兩種批量數(shù)據(jù)插入方法:Bulk和表值參數(shù)(Table-Valued Parameters),高效插入數(shù)據(jù)。
新建數(shù)據(jù)庫(kù):
--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
一.傳統(tǒng)的INSERT方式
先看下傳統(tǒng)的INSERT方式:一條一條的插入(性能消耗越來(lái)越大,速度越來(lái)越慢)
//使用簡(jiǎn)單的Insert方法一條條插入 [慢]
#region [ simpleInsert ]
static void simpleInsert()
{
Console.WriteLine("使用簡(jiǎn)單的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
{
//循環(huán)插入1000條數(shù)據(jù),每次插入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萬(wàn)條數(shù)據(jù)后,顯示此次插入所用時(shí)間
Console.WriteLine(string.Format("Elapsed Time is {0} Milliseconds", sw.ElapsedMilliseconds));
}
Console.ReadKey();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
#endregion
循環(huán)插入1000條數(shù)據(jù),每次插入100條,插入10次,效率是越來(lái)越慢。

二.較快速的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("使用簡(jiǎn)單的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
循環(huán)插入1000條數(shù)據(jù),每次插入100條,插入10次,效率快了很多。

三.使用簡(jiǎn)稱TVPs插入數(shù)據(jù)
打開sqlserrver,執(zhí)行以下腳本:
--Create Table Valued CREATE TYPE BulkUdt AS TABLE (Id int, UserName nvarchar(32), Pwd varchar(16))

成功后在數(shù)據(jù)庫(kù)中發(fā)現(xiàn)多了BulkUdt的緩存表。
使用簡(jiǎn)稱TVPs插入數(shù)據(jù)
//使用簡(jiǎn)稱TVPs插入數(shù)據(jù) [最快]
#region [ 使用簡(jiǎn)稱TVPs插入數(shù)據(jù) ]
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("使用簡(jiǎn)稱TVPs插入數(shù)據(jù)");
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

循環(huán)插入1000條數(shù)據(jù),每次插入100條,插入10次,效率是越來(lái)越慢,后面測(cè)試,將每次插入的數(shù)據(jù)量增大,會(huì)更大的體現(xiàn)TPVS插入的效率。
到此這篇關(guān)于SQL Server批量插入數(shù)據(jù)案例詳解的文章就介紹到這了,更多相關(guān)SQL Server批量插入數(shù)據(jù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SQL2000個(gè)人版 應(yīng)用程序正常初始化失敗0乘以C0000135失敗
應(yīng)用程序正常初始化(0*c0000135)失敗。是什么意思?2011-01-01
SQL?Server日志清理3種實(shí)現(xiàn)方式
這篇文章主要給大家介紹了關(guān)于SQL?Server日志清理3種實(shí)現(xiàn)方式的相關(guān)資料,在數(shù)據(jù)庫(kù)使用很久后日志文件會(huì)累計(jì)的越來(lái)越大,如果硬盤空間不足可能會(huì)導(dǎo)致宕機(jī),需要的朋友可以參考下2023-09-09
揭秘SQL Server 2014有哪些新特性(3)-可更新列存儲(chǔ)聚集索引
可更新的列存儲(chǔ)索引作為SQL Server 2014的一個(gè)關(guān)鍵功能之一,在提升數(shù)據(jù)庫(kù)的查詢性能方面貢獻(xiàn)非常突出。據(jù)微軟統(tǒng)計(jì),在面向OLAP查詢統(tǒng)計(jì)類系統(tǒng)中,相比其他SQL傳統(tǒng)版本的數(shù)據(jù)庫(kù),報(bào)表查詢的性能最大可提升上十倍。2014-08-08
SQL SERVER 表與表之間 字段一對(duì)多sql語(yǔ)句寫法
這篇文章主要介紹了SQL SERVER 表與表之間 字段一對(duì)多sql語(yǔ)句寫法,需要的朋友可以參考下2017-01-01
sqlserver 批量刪除存儲(chǔ)過程和批量修改存儲(chǔ)過程的語(yǔ)句
sqlserver 批量刪除存儲(chǔ)過程和批量修改存儲(chǔ)過程的語(yǔ)句,需要的朋友可以參考下。2011-07-07
SQL Server兩種分頁(yè)的存儲(chǔ)過程使用介紹
這篇文章主要介紹了SQL Server兩種分頁(yè)的存儲(chǔ)過程的使用,需要的朋友可以學(xué)習(xí)下2014-07-07
SQL server使用自定義函數(shù)以及游標(biāo)
最近忙于動(dòng)態(tài)監(jiān)測(cè)軟件的開發(fā),處理有關(guān)標(biāo)準(zhǔn)宗地編碼和區(qū)段編碼關(guān)系,關(guān)系如下表所示2011-10-10

