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, [ ...
随机推荐
- Spring Cloud Config 1 (分布式配置中心)
spring cloud config是spring cloud团队创建的一个全新的项目,用来为分布式系统中的基础设施和微服务应用提供集中化的外部配置支持,它分为服务端和客户端两部分. 服务端也被称为 ...
- 移植RT2870无线网卡驱动到s3c2416
公司项目要用到usb无线网卡,芯片是ralink的RT2870.以下是将其驱动移植到s3c2416的步骤. 1.下载驱动源码,雷凌官网的下载地址是: http://www.ralinktech.com ...
- xcode恢复语法高亮
[xcode恢复语法高亮] 非常简单,在Organizer中删除derivedData.
- copyWithZone详解
[copyWithZone详解] NSObject实现了-copy.+copy.+copyWithZone方法.代码如下: + (id)copy { return (id)self; } + (id) ...
- tomcat在linux服务器上部署应用
连接服务器 服务器地址:xxx.xxx.xxx.xxx 用户名:xxxx 密码:xxxx 进入到服务器中的tomcat路径,关闭服务器,例如 路径:/opt/wzgcyth/apache-tomcat ...
- Rails 和 Django 的深度技术对比
我想以一个免责声明来开始下面的内容.我使用 Django开发网站已经有三年了,众所周知,我喜欢Django.我已经写了一个开源的应用程序( app),并且我已经将补丁发送到了Django.然而,我以尽 ...
- Linux oprofile命令
一.简介 oProfile是Linux平台上的一个功能强大的性能分析工具,支持两种采样(sampling)方式:基于事件的采样(eventbased)和基于时间的采样(timebased),它可以工作 ...
- Celery笔记
异步任务神器 Celery 简明笔记 2016/12/19 · 工具与框架 · Celery, 异步 原文出处: FunHacks 在程序的运行过程中,我们经常会碰到一些耗时耗资源的操作,为了避 ...
- GCC 4.7相对4.6.x的改进点
原文:http://www.iteye.com/news/24628针对C的功能改进: 支持ISO C11标准中的更多特性.除了之前的-std=c1x和-std=gnu1x选项外,GCC现在还支持-s ...
- 第17章-Spring消息
1 异步消息简介 像RMI和Hessian/Burlap这样的远程调用机制是同步的.如图17.1所示,当客户端调用远程方法时,客户端必须等到远程方法完成后,才能继续执行.即使远程方法不向客户端返回任何 ...