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, [ ...
随机推荐
- 【290】Python 常用说明
1. 双击直接运行 python 代码暂停显示的方法:python学习笔记(3)--IDLE双击运行后暂停 需要添加如下代码: import os os.system("pause" ...
- JS中日期处理
- Shell +Cygwinterminal+WinMySQL 传参数授权
前言:新公司因为部分业务原因有好几百组win机器装MySQL授权登录比较麻烦,简单的写了一个shell传值自动授权的脚本,保存复用. #!/bin/bash #author liding@zlhy.c ...
- Part10-C语言环境初始化-C与汇编混合编程lesson4
1.为什么要混合编程 汇编语言:执行效率高:编写繁琐: 执行效率高:能够更直接地控制处理器. c语言:可读性强,移植性好,调试方便. 1.汇编调用c函数 2.c调用汇编函数 汇编语言定义的函数(标号) ...
- Linux 下安装Yaf扩展
1.在官网下载了yaf扩展包 yaf-3.0.3.tgz 2.开始安装yaf扩展 tar zxvf yaf-3.0.3.tgz cd yaf-3.0.3 phpize ./configure --wi ...
- MVC5应用程序生命周期lifecycle
- easyui-dialog 弹窗
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/ ...
- 三年经验的C,超过两题答不出请离开软件界
1.double free是什么问题?申请地址与释放地址不一致会有什么问题? 2.main函数最多有几个参数?各是什么作用? 3.crt是什么?编译器是怎么样连接crt的(描述cl或者gcc方式) 4 ...
- 福大软工1816|K班—alpha冲刺
Part.1 开篇 队名:彳艮彳亍团队 组长博客:戳我进入 作业博客:班级博客本次作业的链接 Part.2 成员汇报 组员1(组长)柯奇豪 过去两天完成了哪些任务 了解前端方面的相关内容,便于后续对进 ...
- 解决chrome浏览器无法得到window.showModalDialog返回值的问题
父页面处理: function ProductList() { var TypeID = window.document.getElementById("Type").valu ...