ADO.NET- 中批量添加数据的几种实现方法比较
在.Net中经常会遇到批量添加数据,如将Excel中的数据导入数据库,直接在DataGridView控件中添加数据再保存到数据库等等。
方法一:一条一条循环添加
通常我们的第一反应是采用for或foreach循环一条一条的添加。这样的方法可想而知,效率肯定很低,可以慢到操作人员无法接受的那种。经过测试(局域网),1W条数据将会耗时3分42秒842毫秒
for (int i = ; i < dgv.Rows.Count; i++)
{
string sql = "insert into .....";
SqlHelper.ExcuteNonQuery(CommandType.Text, sql, null);
}
方法二:每一千条循环添加
也许马上会有人想到Insert多条记录,即"Insert into TableName Values(' ',' ',' '),Values(' ',' ',' ')",这种方法在一定程度上提高不少的效率,但是这种方法有几个弊端。比如说,在SQL Server 2000中它就不支持这种语法,会提示"第 2 行: ',' 附近有语法错误。"的警告,批量操作也就无从谈起。再比如,这种方法么次最多也只能Insert 1000条数据,如果超过了1000条就会报错:"INSERT 语句中行值表达式的数目超出了 1000 行值的最大允许值。"。当然了,我们可以分为几次,每次添加一千条数据,这样还是比方法一的效率高不少。经过测试(局域网),1W条数据将会耗时0分14秒766毫秒
int rowCount = dataGridView1.Rows.Count;
int quotient = rowCount / ; //商
int remainder = rowCount % ; //余数
StringBuilder str = new StringBuilder();
for (int j = ; j < quotient; j++)
{
str.Append("insert into BatchTable values");
for (int i = ; i < ; i++)
{
str.AppendFormat("('{0}','{1}','{2}','{3}','{4}','{5}','{6}','{7}','{8}','{9}','{10}'),"
, dataGridView1[, i].Value, dataGridView1[, i].Value, dataGridView1[, i].Value, dataGridView1[, i].Value,
dataGridView1[, i].Value , dataGridView1[, i].Value, dataGridView1[, i].Value, dataGridView1[, i].Value,
dataGridView1[, i].Value, dataGridView1[, i].Value, dataGridView1[, i].Value);
}
string sql = str.ToString().TrimEnd(',');
SqlHelper.ExcuteNonQuery(CommandType.Text, sql, null);
str.Clear();
}
if (remainder > )
{
str.Append("insert into BatchTable values");
for (int i = ; i < remainder; i++)
{
str.AppendFormat("('{0}','{1}','{2}','{3}','{4}','{5}','{6}','{7}','{8}','{9}','{10}'),"
, dataGridView1[, i].Value, dataGridView1[, i].Value, dataGridView1[, i].Value, dataGridView1[, i].Value
, dataGridView1[, i].Value, dataGridView1[, i].Value, dataGridView1[, i].Value, dataGridView1[, i].Value,
dataGridView1[, i].Value, dataGridView1[, i].Value, dataGridView1[, i].Value);
}
string sql = str.ToString().TrimEnd(',');
SqlHelper.ExcuteNonQuery(CommandType.Text, sql, null);
str.Clear();
}
方法三:使用SqlBulkCopy类批量添加数据
SqlBulkCopy类位于System.Data.SqlClient命名空间下,摘自MSDN:Microsoft SQL Server 提供一个称为 bcp 的流行的命令提示符实用工具,用于将数据从一个表移动到另一个表(表既可以在同一个服务器上,也可以在不同服务器上)。SqlBulkCopy 类允许编写提供类似功能的托管代码解决方案。还有其他将数据加载到 SQL Server 表的方法(例如 INSERT 语句),但相比之下SqlBulkCopy 提供明显的性能优势。使用 SqlBulkCopy 类只能向 SQL Server 表写入数据。但是,数据源不限于 SQL Server;可以使用任何数据源,只要数据可加载到 DataTable 实例或可使用IDataReader 实例读取数据。
采用 SqlBulkCopy类进行批量添加数据将会大大调高效率。经过测试(局域网),1W条数据将会耗时0分0秒292毫秒
public static bool ExcuteNonQuery(DataTable dt)
{
SqlConnection connection = new SqlConnection(connString);
connection.Open();
SqlBulkCopy sqlbulkcopy = new SqlBulkCopy(connection);
sqlbulkcopy.BulkCopyTimeout = ; //超时之前操作完成所允许的秒数
sqlbulkcopy.BatchSize = dt.Rows.Count; //每一批次中的行数
sqlbulkcopy.DestinationTableName = dt.TableName; //服务器上目标表的名称
for (int i = ; i < dt.Columns.Count; i++)
{
sqlbulkcopy.ColumnMappings.Add(i, i); //映射定义数据源中的列和目标表中的列之间的关系
}
sqlbulkcopy.WriteToServer(dt); // 将DataTable数据上传到数据表中
connection.Close();
return true;
}
方法四:利用SQL Server 2008新特性:表值参数,简称TVPS
MSDN中对表值参数的解释:
表值参数提供一种将客户端应用程序中的多行数据封送到 SQL Server 的简单方式,而不需要多次往返或特殊服务器端逻辑来处理数据。 您可以使用表值参数来包装客户端应用程序中的数据行,并使用单个参数化命令将数据发送到服务器。 传入的数据行存储在一个表变量中,然后您可以通过使用 Transact-SQL 对该表变量进行操作。
注意:无法在表值参数中返回数据。 表值参数是只可输入的参数;不支持 OUTPUT 关键字。详情请参见MSDN
在ADO.NET中使用表值参数传递DataTable对象
1、创建数据表对应的表值参数类型,此类型应与数据表结构一致,假如创建数据表的sql语句为
--BatchTable为数据表名称
create table [dbo].[BatchTable](
[Gradation] [nvarchar](10) NULL,
[Column1] [nvarchar](10) NULL,
[Column2] [nvarchar](10) NULL,
[Column3] [nvarchar](10) NULL,
[Column4] [nvarchar](10) NULL,
[Column5] [nvarchar](10) NULL,
[Column6] [nvarchar](10) NULL,
[Column7] [nvarchar](10) NULL,
[Column8] [nvarchar](10) NULL,
[Column9] [nvarchar](10) NULL,
[Column10] [nvarchar](10) NULL
) ON [PRIMARY]
GO
2、那么对应的创建表值参数类型的语句为
--BatchTableTvps为参数类型名称
Create type BatchTableTvps as Table
(
[Gradation] [nvarchar](10) NULL,
[Column1] [nvarchar](10) NULL,
[Column2] [nvarchar](10) NULL,
[Column3] [nvarchar](10) NULL,
[Column4] [nvarchar](10) NULL,
[Column5] [nvarchar](10) NULL,
[Column6] [nvarchar](10) NULL,
[Column7] [nvarchar](10) NULL,
[Column8] [nvarchar](10) NULL,
[Column9] [nvarchar](10) NULL,
[Column10] [nvarchar](10) NULL
)
GO
懒人们一般的做法都是,选中要操作的数据表,单击右键 —> 编写表脚本为 —> Create到 —> 新查询编辑器窗口。然后稍稍修改就行了
3、然后就可以在C#中指定SqlParameter参数对象的属性TypeName为刚刚创建的表值参数类型。
DataTable table = GetDataTable("BatchTable"); //要插入的表
string sql = "insert into BatchTable select * from @BatchTable";
SqlParameter par = new SqlParameter("@BatchTable", SqlDbType.Structured);
par.TypeName = "BatchTableTvps"; //指定表值参数类型
par.Value = table;
SqlParameter[] pars = new SqlParameter[] { par };
int values = SqlHelper.ExcuteNonQuery(CommandType.Text, sql, pars);
SqlBulkCopy类批量添加数据与表值参数TVPS批量添加数据比较
同一环境下,添加1W条数据:SqlBulkCopy耗时292毫秒,TVPS耗时902毫秒
同一环境下,添加10W条数据:SqlBulkCopy耗时5秒768毫秒,TVPS耗时6秒617毫秒
同一环境下,添加20W条数据:SqlBulkCopy耗时11秒791毫秒,TVPS耗时16秒525毫秒
测试源码下载链接:http://download.csdn.net/detail/tracine0513/8060011
ADO.NET- 中批量添加数据的几种实现方法比较的更多相关文章
- .Net中批量添加数据的几种实现方法比较
在.Net中经常会遇到批量添加数据,如将Excel中的数据导入数据库,直接在DataGridView控件中添加数据再保存到数据库等等. 方法一:一条一条循环添加 通常我们的第一反应是采用for或for ...
- (转载)MySQl数据库-批量添加数据的两种方法
方法一:使用excel表格 方法二:使用insert语句(FileWriter批量写入) 使用excel表格 1.打开数据表,按照表的字段在excel中添加数据.注意:表中字段名必须和excel中的名 ...
- SQLSERVER数据库中批量导入数据的几种方法
第一:使用Select Into 语句 如果企业数据库都是采用SQL Server数据库的话,则可以利用select into语句实现数据的导入. select into语句的作用是把数据从另外一个数 ...
- Java模拟数据量过大时批量处理数据的两种实现方法
方法一: 代码如下: import java.util.ArrayList; import java.util.List; /** * 模拟批量处理数据(一) * 当数据量过大过多导致超时等问题可以将 ...
- mybatis 批量添加数据的两种实现方式
做开发的这几年期间经常遇到类似处理这种形式数据的问题,也遇到很多刚刚入行的新同学,发现他们做处理这块,经验不够,今天特地整理了一下,大家都会遇到的几种情况,代码也都粘贴出来了,拿去不谢,有时间大家还是 ...
- mybatis批量添加数据的三种方式
原文地址:https://www.cnblogs.com/gxyandwmm/p/9565002.html
- spring boot之使用通用Mapper批量添加数据
通用Mapper是一款针对mybatis进行扩展的轻量级组件,使用起来非常方便.当调用其针对mysql进行批量添加数据的方法时,发现报错,仔细研究了一番,发现是在使用通用Mapper上出现了问题.下面 ...
- Yii2如何批量添加数据
批量添加这个操作,在实际开发中经常用得到,今天小编抽空给大家整理些有关yii2批量添加的问题,感兴趣的朋友一起看看吧. 在上篇文章给大家介绍了关于浅析Yii2 gridview实现批量删除教程,当然, ...
- EF批量添加数据性能慢的问题的解决方案
//EF批量添加数据性能慢的问题的解决方案 public ActionResult BatchAdd() { using (var db = new ToneRoad.CEA.DbContext.Db ...
随机推荐
- 【 2017 Multi-University Training Contest - Team 9 && hdu 6162】Ch’s gift
[链接]h在这里写链接 [题意] 给你一棵树,每个节点上都有一个权值. 然后给你m个询问,每个询问(x,y,a,b); 表示询问x->y这条路径上权值在[a,b]范围内的节点的权值和. [题解] ...
- Android自己定义View画图实现拖影动画
前几天在"Android画图之渐隐动画"一文中通过画线实现了渐隐动画,但里面有个问题,画笔较粗(大于1)时线段之间会有裂隙.我又改进了一下.这次效果好多了. 先看效果吧: 然后我们 ...
- 关于Altium Designer重新修改某一原件pcb封装的问题
在重新导入的时候可能会影响到类class,所以可能是原理图中没有类吧 上图中的comment的修改是表示下面图片中的 comment栏的改变:
- FPGA实现UHS的一些资料
对使用FPGA和SD卡进行UHS模式通信的评估: 论文:基于FPGA的SD UHS-II卡控制器设计与实现 设计IP:SD UHS-II Host Controller 供应商: System Lev ...
- C++中使用soap toolkit访问webService详解
使用Visual C++开发SOAP客户端应用 使用Visual C++开发SOAP客户端应用 简介 在本篇文章中,我们将讨论如何使用Visual C++开发一个简单的SOAP客户端应用程序,我们还 ...
- 【Android开源框架】使用andbase开发框架实现绘制折线图
在Android中,当有绘制折线图的需求时.大多数人使用的AChartEngine,来进行折线图的绘制.AChartEngine图表引擎确实能够实现折线图的功能.除此之外,我们还能够使用andbase ...
- WebService--概述、JDk实现、AJAX调用
一.Webservice概述 W3C组织对其的定义是,它是一个软件系统,为了支持跨网络的机器间相互操作交互而设计. Webservice服务通常被定义为一组模块化的API,它们可以通过网络进行调用,来 ...
- 《iOS Human Interface Guidelines》——Edit Menu
编辑菜单 用户能够显示一个编辑菜单来在文本视图.网页视图和图像视图运行诸如剪切.粘贴和选择的操作. 你能够调整一些菜单的行为来在你的app中给用户给多的内容控制.比方你能够: 指定哪一个标准菜单命令对 ...
- iOS writeTofile 和对象的序列化
前言:做了一个图片浏览的小demo,支持随意添加.删除图片,图片放大.缩小,带矩形框的截图.随后几篇博客都会详细讲解在此过程中遇到的各种问题.这篇主要讲,在做添加.删除这个功能时,遇到的存文件的问题. ...
- js进阶正则表达式7点数字字母空格(w d s)(小写表原意,大写表反义)(特殊字符要加反斜杠:var reg22=/\W/g)
js进阶正则表达式7点数字字母空格(w d s)(小写表原意,大写表反义)(特殊字符要加反斜杠:var reg22=/\W/g) 一.总结 1.w d s,word digital space 2.特 ...