快速批量插入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 ...
随机推荐
- angularjs的forEach使用
最近一直在写angularjs中的http后台数据交互,存在的问题就是数据传输中数据格式的问题,如何将传输过来的数据转化为自己需要的数据.当然如果你会一点后台语言的话,完全可以用在后台把数据转化为需要 ...
- oracle 解析json格式
1. CREATE OR REPLACE PACKAGE PKG_ANALYSE_COMMON IS -- AUTHOR : YZCHEN -- CREATED : 2013/11/26 14:12: ...
- Linux下nginx生成日志自动切割
1.编辑切割日志的 shell 程序,目录自定 #vi /data/nginx/cut_nginx_log.sh 输入代码: #!/bin/bash # This script run at 00:0 ...
- POJ 2656 Unhappy Jinjin
#include <stdio.h> int main() { ) { int i, n; ; scanf("%d", &n); ) break; ; i &l ...
- redis连接池操作
/** * @类描述 redis 工具 * @功能名 POJO * @author zxf * @date 2014年11月25日 */public final class RedisUtil { p ...
- DD应用实例
1.将本地的/dev/hdb整盘备份到/dev/hdd dd if=/dev/hdb of=/dev/hdd2.将/dev/hdb全盘数据备份到指定路径的image文件dd if=/dev/hdb o ...
- 如何在网页标题栏title加入logo图标?
打开某一个网页会在浏览器的标签栏处显示该网页的标题和图标,当网页被添加到收藏夹或者书签中时也会出现网页的图标,怎么在网页title左边显示网页的logo图标呢? 方法一(被动式): 制作一个ico格式 ...
- php的实参和形参
1.实参是调用函数时候的参数; 2.形参是声明函数时侯的参数, 例如 public function demo($a,$b) { return ; } 如果声明的函数如上,调用时dem ...
- 实现简单的手写涂鸦板(demo源码)
在一些软件系统中,需要用到手写涂鸦的功能,然后可以将涂鸦的结果保存为图片,并可以将"真迹"通过网络发送给对方.这种手写涂鸦功能是如何实现的了?最直接的,我们可以使用Windows提 ...
- Gentoo安装详解(三)-- 配置系统
配置系统 系统信息: 文件系统信息: 创建/etc/fstab nano -w /etc/fstab 网络信息: Host name, Domainname, etc nano -w /etc/con ...