快速批量插入sqlserver方法之我见
--------------------------------------------------------------------------------------------------------------------------
大容量插入三种方法及优劣分析
--------------------------------------------------------------------------------------------------------------------------
/// <summary>
/// bulkcopy类——大容量插入 方法一 使用方便,不牵扯跨域问题,不牵扯数据类型等问题,推荐使用,效率高
/// </summary>
/// <param name="dt">datatable</param>
/// <param name="list">源</param>
/// <param name="tableName">插入表格名称</param>
/// <returns>返回结果</returns>
public static bool PerformBulkCopy(DataTable dt, IList list, string tableName)
{
using (SqlConnection destinationConnection = new SqlConnection(CONN_STRING))
{
destinationConnection.Open();
//开启事务
SqlTransaction sqlbulkTransaction = destinationConnection.BeginTransaction();
using (SqlBulkCopy bulkCopy = new SqlBulkCopy(destinationConnection.ConnectionString))
{
bulkCopy.BatchSize = 500;
bulkCopy.DestinationTableName = tableName;
//根据datatable循环添加映射
for (int i = 0; i < dt.Columns.Count; i++)
{
bulkCopy.ColumnMappings.Add(dt.Columns[i].ColumnName, dt.Columns[i].ColumnName);
}
try
{
//写入数据库
bulkCopy.WriteToServer(dt);
return true;
}
catch (Exception)
{
//回滚操作
sqlbulkTransaction.Rollback();
return false;
}
}
}
}
--------------------------------------------------------------------------------------------------------------------------
/// <summary>
/// 表值参数——大容量插入 方法二 效率最低,在1000条及以下数据时,效率不错,使用较方便,牵扯到数据类型问题
/// </summary>
/// <param name="dt">datatable</param>
private void PerformTableParam(DataTable dt)
{
string connectionString = @"data source=211.144.151.150;initial catalog=sctkNew;persist security info=True;user id=wjh;password=P@ssw0rd";
using (var conn = new SqlConnection(connectionString))
{
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("@usersTable", SqlDbType.Structured) { Value = dt };
cmd.Parameters.Add(param);
cmd.ExecuteNonQuery();
}
}
}
sql语句:
//1.创建表值参数
CREATE TYPE jk_users_bulk_insert AS TABLE (
[VideoTeacher] [nvarchar](100) NULL,
[ImageStype] [nvarchar](100) NULL,
[ImageBig] [nvarchar](1000) NULL
...
)
//2.创建存储过程 参数为表
CREATE PROCEDURE sp_insert_jk_users
@usersTable jk_users_bulk_insert READONLY
AS
INSERT INTO dbo.tb_E_Question(--字段)
SELECT --字段
FROM @usersTable
--------------------------------------------------------------------------------------------------------------------------
///<summary>
///bulk insert ——大容量插入 方法三 效率最高,牵扯到跨域的问题,使用不方便
///</summary>
public void InsertByBlukInsert()
{
//存入sb中,存储试题
StringBuilder shitiSB = new StringBuilder();
foreach (tb_E_Question Question in ListQuestionModel)
{
if (!String.IsNullOrEmpty(Question.QuestionTypeID))
{
//拼写字符串
string shitiModelStr = Question.QuestionID + "|@" +Question.FullFolderId+"|@\\";
shitiSB.Append(shitiModelStr);
}
else
{
if (Question.QuestionTypeID == null)
Ever += "第" + iic + "题在系统里面没有该题型,请确定系统里面有该题型。";
else if (ssid != "true")
Ever += "第" + iic + "题在系统里面已有该题。";
}
}
//不用去掉最后的两个字符
//shitiSB= shitiSB.Remove(shitiSB.Length-2,2);
//写入临时txt文本文件
string fileName=AppDomain.CurrentDomain.BaseDirectory+"\\AdminShiTiImportTemp.txt";
using (FileStream file = new FileStream(fileName, FileMode.Create, FileAccess.Write))
{
using (StreamWriter writer = new StreamWriter(file, Encoding.Unicode))
{
writer.Write(shitiSB);
}
}
//调用Bulk Insert方法插入
tb_E_QuestionService questionServiceBll=new tb_E_QuestionService();
int questionCount= questionServiceBll.BulkInsert(AppDomain.CurrentDomain.BaseDirectory+fileName);
//销毁或清空该文本文件,文件名命名规则:当前用户+文件名
}
sql bluk insert语句:
BULK INSERT dbo.course
FROM '\\127.0.0.1\D_TestFiles\E:\A_yanzhinan_Work\test.txt'
WITH
(
--DATAFILETYPE = 'widenative' ,
FIELDTERMINATOR = ','
,ROWTERMINATOR = ';'
)
---------------------------------------------------附加将集合类转换成DataTable的方法--------------------------------------------------------------
/// <summary>
/// 将集合类转换成DataTable——方法一 没有经过判断null值
/// </summary>
/// <param name="list">集合</param>
/// <returns></returns>
public DataTable ToDataTableOne(IList list)
{
DataTable result = new DataTable();
if (list.Count > 0)
{
PropertyInfo[] propertys = list[0].GetType().GetProperties();
foreach (PropertyInfo prop in propertys )
{
Type t = GetCoreType(prop.PropertyType);
tb.Columns.Add(prop.Name, t);
}
for (int i = 0; i < list.Count; i++)
{
ArrayList tempList = new ArrayList();
foreach (PropertyInfo pi in propertys)
{
object obj = pi.GetValue(list[i], null);
tempList.Add(obj);
}
object[] array = tempList.ToArray();
result.LoadDataRow(array, true);
}
}
return result;
}
/// <summary>
/// 将集合类转换成DataTable——方法二 推荐方案,转换可控性强,null值经过处理
/// </summary>
private DataTable ToDataTableTwo<T>(List<T> items)
{
var tb = new DataTable(typeof(T).Name);
PropertyInfo[] props = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
foreach (PropertyInfo prop in props)
{
//排除null值
Type t = GetCoreType(prop.PropertyType);
//可以使用add的第二个参数,类型参数
tb.Columns.Add(prop.Name, t);
}
foreach (T item in items)
{
var values = new object[props.Length];
int k = 0;
for (int i = 0; i < props.Length; i++)
{
values[i] = props[i].GetValue(item, null);
}
tb.Rows.Add(values);
}
//去除相关无用属性,具体情况具体判断
tb.Columns.Remove("UserAnser");
tb.Columns.Remove("Marked");
tb.Columns.Remove("SelectAnswerList");
tb.Columns.Remove("QuestionType");
return tb;
}
/// <summary>
/// Determine of specified type is nullable
/// </summary>
public static bool IsNullable(Type t)
{
return !t.IsValueType || (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable<>));
}
/// <summary>
/// Return underlying type if type is Nullable otherwise return the type
/// </summary>
public static Type GetCoreType(Type t)
{
if (t != null && IsNullable(t))
{
if (!t.IsValueType)
{
return t;
}
else
{
return Nullable.GetUnderlyingType(t);
}
}
else
{
return t;
}
}
/// <summary>
///将集合类转换成DataTable——方法三 利用IEnumerable 较简洁,但过程不方便控制,null值没有经过判断
/// </summary>
public static DataTable ToDataTableThree<T>(IEnumerable<T> collection)
{
var props = typeof(T).GetProperties();
var dt = new DataTable();
dt.Columns.AddRange(props.Select(p => new DataColumn(p.Name)).ToArray());
object[] pos = new object[dt.Columns.Count];
if (collection.Count() > 0)
{
for (int i = 0; i < collection.Count(); i++)
{
ArrayList tempList = new ArrayList();
foreach (PropertyInfo pi in props)
{
object obj = pi.GetValue(collection.ElementAt(i), pos);
tempList.Add(obj);
}
object[] array = tempList.ToArray();
dt.LoadDataRow(array, true);
}
}
return dt;
}
推荐相关网址:
http://www.cnblogs.com/wlb/archive/2010/03/02/1676136.html
http://blog.csdn.net/zhoufoxcn/article/details/1871514
http://www.cnblogs.com/rush/archive/2012/08/31/2666090.html
快速批量插入sqlserver方法之我见的更多相关文章
- net core天马行空系列-各大数据库快速批量插入数据方法汇总
1.前言 hi,大家好,我是三合.我是怎么想起写一篇关于数据库快速批量插入的博客的呢?事情起源于我们工作中的一个需求,简单来说,就是有一个定时任务,从数据库里获取大量数据,在应用层面经过处理后再把结果 ...
- C# 批量插入数据方法
批量插入数据方法 void InsertTwo(List<CourseArrangeInfo> dtF) { Stopwatch watch = new Stopwatch(); watc ...
- oracle 快速批量插入复杂数据的内容
最近迷上一种批量插入的方法,一句sql解决,将需要插入的数据用with as 的方式查出来,不管多么复杂的sql,都可以用临时表的方式查出来,然后直接插入,这样代码更加清晰 流程也简单 insert ...
- SqlServer 获取 当前地址下 所有数据库字段信息 / 快速 批量插入数据库(TVPs)
SQL执行 --拼装 当前地址下 所有数据库字段信息 BEGIN DECLARE @dataBaseName NVARCHAR(MAX)--数据库名称 DECLARE @tableName NVARC ...
- 三种JDBC批量插入编程方法的比较
JDBC批量插入主要用于数据导入和日志记录因为日志一般都是先写在文件下的等. 我用Mysql 5.1.5的JDBC driver 分别对三种比较常用的方法做了测试 方法一,使用PreparedStat ...
- 在 SQL 中 快速 批量 插入数据的方法
方法1:逐条执行,速度慢. INSERT INTO testimport (name, message) VALUES ('testname', 'jfksdfkdsfjksadljfkdsfjsdl ...
- .net批量插入SqlServer数据库的方法:
using System;using System.Collections.Generic;using System.Configuration;using System.Data;using Sys ...
- java 高效批量插入 sqlserver 数据库
插入1000条:347毫秒 插入1W条:4086毫秒 插入10W条:47953毫秒 同理,批量更新也可以用此方法,只不过没有插入的快, 更新1000条:90秒 更新100条:9秒
- 使用JDBC在MySQL数据库中快速批量插入数据
使用JDBC连接MySQL数据库进行数据插入的时候,特别是大批量数据连续插入(10W+),如何提高效率呢? 在JDBC编程接口中Statement 有两个方法特别值得注意: void addBatch ...
随机推荐
- angular2与VS2015 asp.net core集成使用
首先,需要在VS2015环境下更新到update2,并安装asp.net core环境,并安装Node.js插件. 新建asp.net core项目: 此时,需要先新建npm配置文件,如图: 并定义n ...
- win10下安装Django
Django的核心(1.4+)可以运行在从2.5到2.7之间的任何Python版本. 我的电脑是操作系统是window10 ,内存是4G. 1.下载django 官网地址:https://www.dj ...
- HDU 5758 Explorer Bo
思维,树形$dp$. 首先选择一个度不为$0$的节点作为根节点,将树无根转有根. 这题的突破口就是要求瞬间移动的次数最少. 次数最少,必然是一个叶子节点走到另一个叶子节点,然后瞬间移动一次,再从一个叶 ...
- virtualbox 提示 vboxclient the virtualbox kernel service is not running
更新完Guest的内核之后,Guest下提示" vboxclient the virtualbox kernel service is not running".Guest下执行: ...
- 第一节windows系统安装虚拟机VMware 软件
1,在windows系统下,下载虚拟机软件VMware-workstation-full-10.0.1 2,解压虚拟机软件,安装虚拟机 第一个为虚拟机注册机,第二个为虚拟机安装软件 点击虚拟机安装软件 ...
- JavaScript的DOM(文档对象)基础语法总结1
---恢复内容开始--- 前言:HTML文档可以说由节点构成的集合,DOM节点有: 1). 元素节点:上图中<html>.<body>.<p>等都是元素节点,即标签 ...
- POJ 1922 Ride to School#贪心
(- ̄▽ ̄)-* //C跟着a君骑,然后更快的b君来了,C又跟着b君骑, //接着最快的d君来了,C就去跟着d君了, //最后最快的d君到达目的地时,C也就到了 //所以C的到达时间,就是最早到达的那 ...
- Java 多态 父类和子类方法的访问控制权限
Java 多态 父类和子类方法的访问控制权限 @author ixenos 父类和子类方法的访问控制权限 继承是为了扩展类的功能,而这种扩展显然就是对一个原始类的扩展,目的还是向上转型来调用,所以这就 ...
- shp文件显示
开发环境 Win7, VS2010 Sp1 QGIS 2.01 #include <qgsapplication.h> #include <qgsproviderregistry.h ...
- 【转】ActiveMQ与虚拟通道
郑重提示,本文转载自http://shift-alt-ctrl.iteye.com/blog/2065436 ActiveMQ提供了虚拟通道的特性(Virtual Destination),它允许一个 ...