SqlServer批量插入(SqlBulkCopy、表值参数)
创建了一个用来测试的Student表:
CREATE TABLE [dbo].[Student](
[ID] [int] PRIMARY KEY NOT NULL,
[Num] [varchar](10) NULL,
[Name] [nvarchar](64) NULL,
[Age] [int] NULL
)
一、SqlBulkCopy类:使用数据库BCP协议进行数据的批量复制,每一批的数量大约800条。
/// <summary>
/// 批量插入SqlBulkCopy
/// </summary>
/// <param name="dt"></param>
/// <param name="tableName">表名</param>
public static void BatchInsertBySqlBulkCopy(DataTable dt, string tableName)
{
using (SqlBulkCopy sbc = new SqlBulkCopy(connString))
{
sbc.BatchSize = dt.Rows.Count;
sbc.BulkCopyTimeout = ;
sbc.DestinationTableName = tableName;
for (int i = ; i < dt.Columns.Count; i++)
{
sbc.ColumnMappings.Add(dt.Columns[i].ColumnName, i);
}
//全部写入数据库
sbc.WriteToServer(dt);
}
}
5万条数据插入花了2秒的时间:
二、表值参数:也叫表变量参数,使用用户定义的表类型来声明,简单理解就是可以把一个表当做参数传递。
CREATE TYPE [dbo].[mytb_student] AS TABLE(
[ID] [int] NOT NULL,
[Num] [varchar](10) NULL,
[Name] [nvarchar](64) NULL,
[Age] [int] NULL
)
/// <summary>
/// 批量插入使用表值参数
/// </summary>
/// <param name="dt"></param>
public static void BatchInsertByTableValue(DataTable dt, string sqlText)
{
using (SqlConnection sqlConn = new SqlConnection(connString))
{
using (SqlCommand sqlCmd = new SqlCommand(sqlText, sqlConn))
{
//把DataTable当做参数传入
SqlParameter sqlPar = sqlCmd.Parameters.AddWithValue("@dt", dt);
//指定表值参数中包含的构造数据的特殊数据类型。
sqlPar.SqlDbType = SqlDbType.Structured;
sqlPar.TypeName = "dbo.mytb_student";//表值参数名称
sqlConn.Open();
sqlCmd.ExecuteNonQuery();
}
}
}
同样插入5万条数据,也是花了2秒的时间。
总结:SqlServer数据库批量插入除了使用SqlBulkCopy和表值参数,还可以使用SqlDataAdapter的Update方法,经过本人测试,在数据量越大的情况下,使用SqlBulkCopy的性能是最好的。
三、在SqlBulkCopy和表值参数进行批量插入时,DataTable列的赋值顺序必须和DB中的表类型定义的字段顺序一致。
IF NOT EXISTS(SELECT * FROM sys.table_types WHERE name = 'type_im_check_detail' AND is_user_defined = 1)
BEGIN
CREATE TYPE type_im_check_detail AS TABLE
(
-- 字段定义顺序
[sheet_no] [varchar](18) NOT NULL,
[item_no] [varchar](40) NOT NULL,
check_date DATETIME null,
in_price NUMERIC(16,4) null,
sale_price NUMERIC(16,4) null,
real_qty NUMERIC(16,4) null,
recheck_qty NUMERIC(16,4) null,
memo NVARCHAR(100) NULL,
item_barcode VARCHAR(40) null,
row_id NUMERIC(16,4) null,
produce_date DATETIME null,
valid_date DATETIME null,
stock_qty NUMERIC(16,4) null
)
END
GO IF NOT EXISTS(SELECT * FROM sys.table_types WHERE name = 'type_im_sheet_barcode_qty' AND is_user_defined = 1)
BEGIN
CREATE TYPE type_im_sheet_barcode_qty AS TABLE
(
-- 字段定义顺序
trans_no VARCHAR(2) NOT NULL,
[sheet_no] [varchar](18) NOT NULL,
line_no INT NOT NULL,
[item_no] [varchar](30) NOT NULL,
item_barcode VARCHAR(38) NOT NULL,
qty NUMERIC(16,4) NULL,
qty2 NUMERIC(16,4) NULL,
qty3 NUMERIC(16,4) NULL
)
END
GO IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID('pr_insert_im_check_detail') AND OBJECTPROPERTY(id, N'IsProcedure') = 1)
BEGIN
DROP PROCEDURE dbo.pr_insert_im_check_detail
END
GO
CREATE PROCEDURE dbo.pr_insert_im_check_detail
(
@detail type_im_check_detail READONLY,
@barcodeDetail type_im_sheet_barcode_qty READONLY
)
AS
BEGIN
SET XACT_ABORT ON
BEGIN TRANSACTION INSERT t_im_check_detail (sheet_no, item_no, check_date, in_price, sale_price, real_qty, recheck_qty, memo, item_barcode, row_id, produce_date, valid_date,stock_qty)
SELECT sheet_no,item_no,check_date,in_price,sale_price,real_qty,recheck_qty,memo,item_barcode,row_id,produce_date,valid_date,stock_qty
FROM @detail INSERT t_im_sheet_barcode_qty (trans_no,sheet_no, item_no,line_no,item_barcode, qty)
SELECT trans_no,sheet_no, item_no,line_no,item_barcode, qty
FROM @barcodeDetail COMMIT TRANSACTION
SET XACT_ABORT OFF
END
GO
// DataTable列定义顺序
private DataTable GetNewDetailTable()
{
DataTable dt = new DataTable();
dt.Columns.Add("sheet_no");
dt.Columns.Add("item_no");
dt.Columns.Add("check_date");
dt.Columns.Add("in_price");
dt.Columns.Add("sale_price");
dt.Columns.Add("real_qty");
dt.Columns.Add("recheck_qty");
dt.Columns.Add("memo");
dt.Columns.Add("item_barcode");
dt.Columns.Add("row_id");
dt.Columns.Add("produce_date");
dt.Columns.Add("valid_date");
dt.Columns.Add("stock_qty"); return dt;
} private DataTable GetNewBarcodeDetailTable()
{
DataTable dt = new DataTable();
dt.Columns.Add("trans_no");
dt.Columns.Add("sheet_no");
dt.Columns.Add("line_no");
dt.Columns.Add("item_no");
dt.Columns.Add("item_barcode");
dt.Columns.Add("qty");
dt.Columns.Add("qty2");
dt.Columns.Add("qty3"); return dt;
}
#region init table
DataTable dt = GetNewDetailTable();
foreach (var item in details)
{
// datatable赋值顺序
DataRow row = dt.NewRow();
row["sheet_no"] = item.sheet_no;
row["item_no"] = item.item_no;
row["check_date"] = item.check_date;
row["in_price"] = item.in_price;
row["sale_price"] = item.sale_price;
row["real_qty"] = item.real_qty;
row["recheck_qty"] = item.recheck_qty;
row["memo"] = item.memo;
row["item_barcode"] = item.item_barcode;
row["row_id"] = item.row_id;
row["produce_date"] = item.produce_date;
row["valid_date"] = item.valid_date;
row["stock_qty"] = item.stock_qty; dt.Rows.Add(row);
} var dtBarcode = GetNewBarcodeDetailTable();
foreach (var item in barcodeDetail)
{
//datatable列赋值顺序
DataRow row = dtBarcode.NewRow();
row["trans_no"] = "CR";
row["sheet_no"] = item.sheet_no;
row["line_no"] = ;
row["item_no"] = item.item_no;
row["item_barcode"] = item.item_barcode;
row["qty"] = item.qty;
row["qty2"] = 0.00;
row["qty3"] = 0.00; dtBarcode.Rows.Add(row);
}
#endregion SqlParameter[] paras = new SqlParameter[] {
new SqlParameter("@detail", SqlDbType.Structured) { Value = dt, TypeName = "type_im_check_detail" },
new SqlParameter("@barcodeDetail", SqlDbType.Structured) { Value = dtBarcode, TypeName = "type_im_sheet_barcode_qty" }
};
Repository.Database.ExecuteSqlCommand("pr_insert_im_check_detail @detail,@barcodeDetail", paras);
**********转载:https://blog.csdn.net/chwenbin/article/details/79112570
SqlServer批量插入(SqlBulkCopy、表值参数)的更多相关文章
- SQLServer 批量插入数据的两种方法
SQLServer 批量插入数据的两种方法-发布:dxy 字体:[增加 减小] 类型:转载 在SQL Server 中插入一条数据使用Insert语句,但是如果想要批量插入一堆数据的话,循环使用Ins ...
- sqlserver数据库批量插入-SqlBulkCopy
当想在数据库中插入大量数据时,使用insert 不仅效率低,而且会导致一系列的数据库性能问题 当使用insert语句进行插入数据时.我使用了两种方式: 每次插入数据时,都只插入一条数据库,这个会导致每 ...
- Mybatis 针对ORACLE和MYSQL的批量插入与多参数批量删除
今天利用Mybatis的<for each>标签做oracle的批量插入数据时,发现和MySQL数据库有区别.在此记录下,以防之后再踩坑. 一.批量插入: 1.controller: /* ...
- SqlServer——批量插入数据
像Major表里面批量插入数据演示: 代码如下: Declare @I int Set @I= Begin Tran InsertData: Insert into Major values(@I,' ...
- Mybatis 插入与批量插入以及多参数批量删除
实体类: import java.io.Serializable; public class AttachmentTable implements Serializable { private sta ...
- sqlserver批量插入数据问题
下午做一个批量添加的功能,自动添加的那种,总是没有达到理想情况,后来请教师傅,给了这个批量添加的代码,一改果然好了,敬佩之情油然而生哈.分享下~ insert into t_ShopApplicati ...
- 批量插入 SqlBulkCopy的测试
关于SqlBulkCopy的测试 最近要做.net关于sql大量插入,找到了sqlbulkcopy(自己google下,应该很多说明了)这个好东西,于是测试下性能,用了三个方法对比: 1)直接用ado ...
- 简单的sqlserver批量插入数据easy batch insert data use loop function in sqlserver
--example 1: DECLARE @pid INT,@name NVARCHAR(50),@level INT,@i INT,@column2 INT SET @pid=0 SET @name ...
- C# 数据库批量插入数据之 —— SqlBulkCopy、表值参数
创建了一个用来测试的Student表: CREATE TABLE [dbo].[Student]( [ID] [int] PRIMARY KEY NOT NULL, ) NULL, ) NULL, [ ...
随机推荐
- 15-EasyNetQ之对延迟消息插件的支持
RabbitMQ延迟消息插件仍然在实验阶段.你使用这个功能要自担风险. RabbitMQ延迟消息插件为RabbitMQ增加了新的交换机类型,允许延时消息投递. EasyNetQ为交换机通过定义一种新的 ...
- Zookeeper 基础、工作流、ZAP协议
ZooKeeper 基础 在深入了解ZooKeeper的运作之前,让我们来看看ZooKeeper的基本概念.[1] 我们将在本章中讨论以下主题:1.Architecture(架构)2.Hierarch ...
- java Web jsp四大作用域和九大内置对象
JSP中的四大作用域:page.request.session.application 这四大作用域,其实就是其九大内置对象中的四个,为什么说他们也是JSP的四大作用域呢?因为这四个对象都能存储数据, ...
- POJ 3169 C - Layout
题意 有n头奶牛从1到n编号,按照编号顺序站成一排,有可能有多头奶牛站在同一个坐标上.一些奶牛互相喜欢,所以他们的距离不能大于某个距离,一些奶牛互相讨厌,所以他们的距离不能小于某个距离,请计算如果可能 ...
- Gym 101128 B Black Vienna
题意 有A-Z 26张牌,现在从中抽出3张牌,并把剩下的23张牌分给选手1和2,现在有n次询问,每次询问一个选手是否有某两张牌,和选手的回答.回答说自己有这两张牌中的几张,问拿出的三张牌有多少种方案能 ...
- [luogu3369]普通平衡树(替罪羊树模板)
解题关键:由于需要根据平衡进行重建,所以不能进行去重,否则无法保证平衡性. #include<cstdio> #include<cstring> #include<alg ...
- android:gravity设置居中的问题
如果设置一个Button的android:gravity="center" android:text="按钮",则是设置了“按钮”两个字在Button中居中显示 ...
- 22-Two(公共子序列的个数)
http://acm.hdu.edu.cn/showproblem.php?pid=5791 Two Time Limit: 2000/1000 MS (Java/Others) Memory ...
- 41、OrthoMCL和mcl软件进行基因家族分析
转载:http://www.realbio.cn/news/124.html https://blog.csdn.net/seallama/article/details/43820763 http: ...
- Luogu 3698 [CQOI2017]小Q的棋盘
BZOJ 4813 虽然数据范围很迷人,但是想树形$dp$没有前途. 先发现一个事情,就是我们可以先选择一条链,最后要走到这一条链上不回来,走到链上的点每一个只需要一步,而如果要走这条链之外的点,一个 ...