C# 使用SqlBulkCopy类批量复制大数据
用途说明:
前些日子,公司要求做一个数据导入程序,要求将Excel数据,大批量的导入到数据库中,尽量少的访问数据库,高性能的对数据库进行存储。于是在网上进行查找,发现了一个比较好的解决方案,就是采用SqlBulkCopy来处理存储数据。SqlBulkCopy存储大批量的数据非常的高效,就像这个方法的名字一样,可以将内存中的数据表直接的一次性的存储到数据库中,而不需要一次一次的向数据库Insert数据。初次实验,百万级别的数据表,也只需几秒时间内就可以完全的存入数据库中,其速度,比传统的Insert方法不止快很多倍
MSDN摘要:Microsoft SQL Server 提供一个称为 bcp 的流行的命令提示符实用工具,用于将数据从一个表移动到另一个表(表既可以在同一个服务器上,也可以在不同服务器上)。SqlBulkCopy 类允许编写提供类似功能的托管代码解决方案。还有其他将数据加载到 SQL Server 表的方法(例如 INSERT 语句),但相比之下 SqlBulkCopy 提供明显的性能优势。
使用 SqlBulkCopy 类只能向 SQL Server 表写入数据。但是,数据源不限于 SQL Server;可以使用任何数据源,只要数据可加载到 DataTable 实例或可使用IDataReader 实例读取数据。
/// <summary>
///
/// </summary>
/// <param name="connectionString">目标连接字符</param>
/// <param name="TableName">目标表</param>
/// <param name="dt">源数据</param>
private void SqlBulkCopyByDatatable(string connectionString, string TableName, DataTable dt)
{
using (SqlConnection conn = new SqlConnection(connectionString))
{
using (SqlBulkCopy sqlbulkcopy =new SqlBulkCopy(connectionString, SqlBulkCopyOptions.UseInternalTransaction))
{
try
{
sqlbulkcopy.DestinationTableName = TableName;
for (int i = 0; i < dt.Columns.Count; i++)
{
sqlbulkcopy.ColumnMappings.Add(dt.Columns[i].ColumnName, dt.Columns[i].ColumnName);
}
sqlbulkcopy.WriteToServer(dt);
}
catch (System.Exception ex)
{
throw ex;
}
}
}
}

如果,大家使用SQL Server 2008,它提供一个新的功能表变量(Table Parameters)可以将整个表数据汇集成一个参数传递给存储过程或SQL语句。它的注意性能开销是将数据汇集成参数(O(数据量))。
现在,我们修改之前的代码,在SQL Server中定义我们的表变量,具体定义如下:
-- =============================================
-- Author: JKhuang
-- Create date: 08/16/2012
-- Description: Declares a user table paramter.
-- =============================================
CREATE TYPE jk_users_bulk_insert AS TABLE (
user_login varchar(60),
user_pass varchar(64),
user_nicename varchar(50),
user_email varchar(100),
user_url varchar(100),
user_activation_key varchar(60),
user_status int,
display_name varchar(250)
)
上面,我们定义了一个表参数jk_users_bulk_insert,接着我们定义一个存储过程接受表参数jk_users_bulk_insert,具体定义如下:
-- =============================================
-- Author: JKhuang
-- Create date: 08/16/2012
-- Description: Creates a stored procedure, receive
-- a jk_users_bulk_insert argument.
-- =============================================
CREATE PROCEDURE sp_insert_jk_users
@usersTable jk_users_bulk_insert READONLY
AS
INSERT INTO jk_users (user_login, user_pass, user_nicename, user_email, user_url,
user_activation_key, user_status, display_name, user_registered)
SELECT user_login, user_pass, user_nicename, user_email, user_url,
user_activation_key, user_status, display_name, GETDATE()
FROM @usersTable
接下我们在客户端代码中,调用存储过程并且将表作为参数方式传递给存储过程。
var sw = Stopwatch.StartNew();
using (var conn = new SqlConnection(ConfigurationManager.ConnectionStrings["SQLCONN2"].ToString()))
{
conn.Open();
//// Invokes the stored procedure.
using (var cmd = new SqlCommand("sp_insert_jk_users", conn))
{
cmd.CommandType = CommandType.StoredProcedure;
//// Adding a "structured" parameter allows you to insert tons of data with low overhead
var param = new SqlParameter("@userTable", SqlDbType.Structured) { Value = dt };
cmd.Parameters.Add(param);
cmd.ExecuteNonQuery();
}
}
sw.Stop();
现在,我们重新执行写入操作发现写入效率与SqlBulkCopy相当。

///批量插入实例------------------------------------------------------------个人案例
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace Impoort
{
class Program
{
public static PQMEntities db = new PQMEntities();
static void Main(string[] args)
{ var users = db.Database.SqlQueryForDataTatable("select * from Right_Users", null);
SqlBulkCopyByDatatable(db.Database.Connection.ConnectionString, "Right_UserTemp", users);
}
private static void SqlBulkCopyByDatatable(string connectionString, string TableName, DataTable dt)
{
using (SqlConnection conn = new SqlConnection())
{
using (SqlBulkCopy sqlbulkcopy = new SqlBulkCopy(connectionString, SqlBulkCopyOptions.UseInternalTransaction))
{
try
{
sqlbulkcopy.DestinationTableName = TableName;
for (int i = 0; i < dt.Columns.Count; i++)
{
sqlbulkcopy.ColumnMappings.Add(dt.Columns[i].ColumnName, dt.Columns[i].ColumnName);
}
sqlbulkcopy.WriteToServer(dt);
}
catch (System.Exception ex)
{
throw ex;
}
}
}
} }
public static class a
{
public static DataTable SqlQueryForDataTatable(this Database db,
string sql,
SqlParameter[] parameters)
{ SqlConnection conn = new System.Data.SqlClient.SqlConnection();
conn.ConnectionString = db.Connection.ConnectionString;
if (conn.State != ConnectionState.Open)
{
conn.Open();
}
SqlCommand cmd = new SqlCommand();
cmd.Connection = conn;
cmd.CommandText = sql; if (parameters!=null&¶meters.Length > 0)
{
foreach (var item in parameters)
{
cmd.Parameters.Add(item);
}
} SqlDataAdapter adapter = new SqlDataAdapter(cmd);
DataTable table = new DataTable();
adapter.Fill(table);
return table;
}
} }
C# 使用SqlBulkCopy类批量复制大数据的更多相关文章
- 使用SqlBulkCopy类批量复制大数据
using System; using System.Configuration; using System.Data; using System.Data.SqlClient; using Syst ...
- .Net批量插入数据到SQLServer数据库,System.Data.SqlClient.SqlBulkCopy类批量插入大数据到数据库
批量的的数据导入数据库中,尽量少的访问数据库,高性能的对数据库进行存储. 采用SqlBulkCopy来处理存储数据.SqlBulkCopy存储大批量的数据非常的高效,将内存中的数据表直接的一次性的存储 ...
- 用.net中的SqlBulkCopy类批量复制数据 (转载)
在软件开发中,把数据从一个地方复制到另一个地方是一个普遍的应用. 在很多不同的场合都会执行这个操作,包括旧系统到新系统的移植,从不同的数据库备份数据和收集数据. .NET 2.0有一个SqlBulkC ...
- 使用asp.net 2.0中的SqlBulkCopy类批量复制数据
介绍:在软件开发中,把数据从一个地方复制到另一个地方是一个普遍的应用. 在很多不同的场合都会执行这个操作,包括旧系统到新系统的移植,从不同的数据库备份数据和收集数据. ASP.NET 2.0有一个Sq ...
- C# 使用 SqlBulkCopy 类批量复制数据到数据库
最近公司需要优化导入的问题,由于之前使用的方式是生成 Insert 语句插入数据库,数据量小的时候还行,但是随着发展数据量渐渐大了,之前的方法性能就跟不上了,于是发现了 SqlBulkCopy 这个类 ...
- 使用SQL语句的子查询批量复制表数据
批量复制表数据这里有两种方法,下面分别来介绍这两种方法: 一.手动创建新表,然后复制数据 如果是要复制整个表的话,可以使用SQL SERVER自动生成CREATE脚本: 然后在脚本中改改表名就可以了, ...
- C# SqlBulkCopy类批量导入数据
特别注意 sqlbulkcopy.ColumnMappings.Add(dt.Columns[i].ColumnName, dt.Columns[i].ColumnName); 插入的时候列的顺序可 ...
- C# SqlBulkCopy类批量导入 测试
一.功能说明 1.可以选择,只导入部分列,或者导入全部列. 2.导入速度的确比一般sql要快. 3.不用写sql语句 ----------------------------------------- ...
- mysql+php+pdo批量添加大数据
1.使用insert into插入 ini_set('max_execution_time','0');//限制超时时间,因为第一种时间较长,索性设为0不限制 $pdo = new PDO(" ...
随机推荐
- Linux ubuntu安装
http://www.ubuntu.org.cn/download/alternative-downloads 下载地址: http://releases.ubuntu.com/ 国内镜像: http ...
- golang使用yaml格式解析构建配置文件
现在主流的配置文件格式有这么几种,xml.yaml.config… xml就算了,太挫了,太土, 太繁琐… config 就是mysql,apache my.cnf的那种格式,这个格式适合功能分层, ...
- c#JS调用
using MSScriptControl; using System; using System.Collections.Generic; using System.Reflection; usin ...
- no result defined for action
1.no result defined for action .......and result input 或者 no result defined for action .......and ...
- 谈一谈IOC、DI
Inversion of control(控制反转) 原来由类库主动去创建对象的方式变为容器装配的方式,装配的方式:设置配置文件. 对象由IOC容器管理,包括创建.释放.存在形式.生命周期的管理等. ...
- [webpack] devtool配置对比
文件结构 -src -views -essay -list.js -detail.js -index.js -webpack.config.js 文件内容 [/src/.../index.js] im ...
- spring-poi-excle往单元格写入图片
HSSF是POI工程对Excel 97(-2007)文件操作的纯Java实现 XSSF是POI工程对Excel 2007 OOXML (.xlsx)文件操作的纯Java实现 在POI中有HSSFPat ...
- opencv 比较直方图方式 进行人脸检测对比
完整opencv(emgucv)人脸.检测.采集.识别.匹配.对比 //成对几何直方图匹配 public static string MatchHist() ...
- 动态规划(DP)基础
DP基础 简单dp 背包问题 记忆化搜索 简单dp 数字三角形 给一个数字构成的三角形,求从顶端走到底部的一条路径,使得路径上的和最大(或者最小). 1 2 3 6 5 4 Example_1 7 3 ...
- Jedis测试redis
首先:Jedis是redis的java版本的客户端. public class JedisTest { //单机版测试Jedis,不使用连接池 @Test public void testJedis( ...