快速批量插入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 ...
随机推荐
- System.InvalidOperationException nested transactions are not supported
如下bll方法,在执行时会报事务嵌套异常.bll方法里开启了分布式事务,dal方法里又启动了数据库事务.通过查看异常堆栈,发现异常是在执行BillsDal.Add(bill);方法里的var tran ...
- Python操作IHTMLDocument2用于自动化测试
有些软件的界面采用Win32窗口嵌套一个IE控件,用Spy++只能识别出一个Internet Explorer_Server控件.常用的几个API函数无法取到IE控件里面的内容,更无法对里面的控件进行 ...
- js--性能优化(转)
前言 一直在学习javascript,也有看过<犀利开发Jquery内核详解与实践>,对这本书的评价只有两个字犀利,可能是对javascript理解的还不够透彻异或是自己太笨,更多的是自己 ...
- dplyr 数据操作 数据过滤 (filter)
在R的使用过程中我们几乎都绕不开Hadley Wickham 开发的几个包,前面说过的ggplot2.reshape2以及即将要讲的dplyr 因为这几个包可以非常轻易的使我们从复杂的数据操作中逃离, ...
- POJ 1716 Integer Intervals#贪心
(- ̄▽ ̄)-* //求一个集合,这个集合与任意一个区间的交集,需至少有两个数字 //贪心过程:按n个区间的最右值从小到大对区间进行排列, //集合首先取第一个区间的最右两个数字, //到第二个区间, ...
- 如何安全退出已调用多个Activity的Application?
如何退出Activity?如何安全退出已调用多个Activity的Application? 退出Activity直接调用finish()方法 //用户点击back键就是退出一个Activity 退出 ...
- 笨方法学python--参数,解包,变量
1 cmd中执行 python ex11.py, ex11.py部分也是所谓的"参数". 2 from sys import argv script, first, second, ...
- yii2.0图片上传
在根目录下夹uploads文件夹 控制器 UploadController.php <?php namespace frontend\controllers; use Yii; use fron ...
- POJ1410 Intersection 计算几何
题目大意:给出一个线段的两端,和矩形两端(不一定是左上和右下),问线段是否与矩形相交(若线段在矩形内也算相交).这题蒸鹅心-- 题目思路:判断所有情况:线段是否在矩形内,线段内一点是否在矩形内,线段是 ...
- UEFI BIOS模式下Windows系统启动过程以及引导文件修复方法
有关UEFI BIOS基础知识的简介,一年前在网易博客做过详细的概述.鉴于某些网友仍然对UEFI下Windows的启动过程不甚了解,虽然网上有各式各样的启动修复工具,但是对于新手来说,如果不明白其中的 ...