转载:http://www.cnblogs.com/flyinghigher/archive/2010/08/12/1798008.html

   http://www.myexception.cn/sql-server/353508.html

用的ADO.Net entity frameWork,也是实体数据的访问方式,等到保存数据(database.SaveChanges())时候,居然一小时没有写完,遂不解,仔细分析,按这样速度需要7个小时。于是换方式,用ADO.net 数据集方式进行,于是用数据集的update,也得三个小时的时间吧。

接下来换sql语句的方式,每几万条数据的时候就执行一次sql的连接字符串,这里用到了stringBuilder,但是速度也是不敢恭维。

第二天,发现了SqlBulkCopy,批量复制,还真是好用,具体用法请查MSDN,请注意设置它的超时时间BulkCopyTimeout属性,否则可是会超时的哦,不过千万级的数据还是会内存溢出的,这里我采用了分批进行复制的方法,即分两次或者三次把这些数据复制到不同的数据表中,最后用T -sql语句进行数据表的对拷。

补充一下:最后用时不超过10分钟。

利用.NET2005表中的一个类 SqlBulkCopy

利用bcp的方式:

private bool SqlBulkCopy(DataTable dt){SqlConnection cnnSql = new SqlConnection("USER ID=sa;PASSWORD=;INITIAL CATALOG=test;DATA SOURCE=.;");cnnSql.Open();try{startTime = DateTime.Now;//数据批量导入sqlserver,创建实例    SqlBulkCopyOptions.UseInternalTransaction采用事务  复制失败自动回滚System.Data.SqlClient.SqlBulkCopy sqlbulk = new System.Data.SqlClient.SqlBulkCopy(cnnSql);//, SqlBulkCopyOptions.UseInternalTransaction);// System.Data.SqlClient.SqlBulkCopy sqlbulk = new System.Data.SqlClient.SqlBulkCopy(System.Configuration.ConfigurationSettings.AppSettings["ConStr"], SqlBulkCopyOptions.UseInternalTransaction);sqlbulk.SqlRowsCopied +=new SqlRowsCopiedEventHandler(OnRowsCopied); //订阅复制完成后的方法,参数是 sqlbulk.NotifyAfter的值sqlbulk.NotifyAfter = dt.Rows.Count;//目标数据库表名sqlbulk.DestinationTableName = "INVTDA";//数据集字段索引与数据库字段索引映射sqlbulk.ColumnMappings.Add(0, 0);sqlbulk.ColumnMappings.Add(1, 1);sqlbulk.ColumnMappings.Add(3, 3);sqlbulk.ColumnMappings.Add(4, 4);sqlbulk.ColumnMappings.Add(5, 5);sqlbulk.ColumnMappings.Add(6, 6);sqlbulk.ColumnMappings.Add(7, 7);sqlbulk.ColumnMappings.Add(8, 8);sqlbulk.ColumnMappings.Add(9, 9);sqlbulk.ColumnMappings.Add(10, 10);sqlbulk.ColumnMappings.Add(11, 11);sqlbulk.ColumnMappings.Add(12, 12);sqlbulk.ColumnMappings.Add(13, 13);sqlbulk.ColumnMappings.Add(14, 14);//导入sqlbulk.WriteToServer(dt);sqlbulk.Close();return true;}catch (Exception ex){throw new Exception(ex.Message);}finally{dt.Dispose();cnnSql.Close();}}
 sqlbulk.SqlRowsCopied +=new SqlRowsCopiedEventHandler(OnRowsCopied); //订阅复制完成后的方法,参数是 sqlbulk.NotifyAfter的值sqlbulk.NotifyAfter = dt.Rows.Count;
------解决方案--------------------------------------------------------
将oledb读取的excel数据快速插入的sqlserver中,很多人通过循环来拼接sql,这样做不但容易出错而且效率低下,最好的办法是使用bcp,也就是System.Data.SqlClient.SqlBulkCopy 类来实现。不但速度快,而且代码简单,下面测试代码导入一个6万多条数据的sheet,包括读取(全部读取比较慢)在我的开发环境中只需要10秒左右,而真正的导入过程只需要4.5秒。using System;
using System.Data;
using System.Windows.Forms;
using System.Data.OleDb;
namespace WindowsApplication2
{public partial class Form1 : Form{public Form1(){InitializeComponent();}private void button1_Click(object sender, EventArgs e){//测试,将excel中的sheet1导入到sqlserver中string connString = "server=localhost;uid=sa;pwd=sqlgis;database=master";System.Windows.Forms.OpenFileDialog fd = new OpenFileDialog();if (fd.ShowDialog() == DialogResult.OK){TransferData(fd.FileName, "sheet1", connString);}}public void TransferData(string excelFile, string sheetName, string connectionString){DataSet ds = new DataSet();try{//获取全部数据string strConn = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=" + excelFile + ";" + "Extended Properties=Excel 8.0;";OleDbConnection conn = new OleDbConnection(strConn);conn.Open();string strExcel = "";OleDbDataAdapter myCommand = null;strExcel = string.Format("select * from [{0}$]", sheetName);myCommand = new OleDbDataAdapter(strExcel, strConn);myCommand.Fill(ds, sheetName);//如果目标表不存在则创建string strSql = string.Format("if object_id('{0}') is null create table {0}(", sheetName);foreach (System.Data.DataColumn c in ds.Tables[0].Columns){strSql += string.Format("[{0}] varchar(255),", c.ColumnName);}strSql = strSql.Trim(',') + ")";using (System.Data.SqlClient.SqlConnection sqlconn = new System.Data.SqlClient.SqlConnection(connectionString)){sqlconn.Open();System.Data.SqlClient.SqlCommand command = sqlconn.CreateCommand();command.CommandText = strSql;command.ExecuteNonQuery();sqlconn.Close();}//用bcp导入数据using (System.Data.SqlClient.SqlBulkCopy bcp = new System.Data.SqlClient.SqlBulkCopy(connectionString)){bcp.SqlRowsCopied += new System.Data.SqlClient.SqlRowsCopiedEventHandler(bcp_SqlRowsCopied);bcp.BatchSize = 100;//每次传输的行数bcp.NotifyAfter = 100;//进度提示的行数bcp.DestinationTableName = sheetName;//目标表bcp.WriteToServer(ds.Tables[0]);}}catch (Exception ex){System.Windows.Forms.MessageBox.Show(ex.Message);}}//进度显示void bcp_SqlRowsCopied(object sender, System.Data.SqlClient.SqlRowsCopiedEventArgs e){this.Text = e.RowsCopied.ToString();this.Update();}}
}
上面的TransferData基本可以直接使用,如果要考虑周全的话,可以用oledb来获取excel的表结构,并且加入ColumnMappings来设置对照字段,这样效果就完全可以做到和sqlserver的dts相同的效果了。获取excel结构的方法可以参考我先前的文章http://blog.csdn.net/jinjazz/archive/2008/05/13/2441635.aspx

转载于:https://www.cnblogs.com/bfy-19/archive/2013/04/02/2994956.html

sqlserver数据库中批量写入海量数据相关推荐

  1. [转-记] 批量解密SQLSERVER数据库中的各种对象的工具dbForge SQL Decryptor2.1.11

    原文链接:批量解密SQLSERVER数据库中的各种对象的工具dbForge SQL Decryptor - 桦仔 - 博客园 ------------------------------------- ...

  2. 获取SQLServer数据库中所有表

    对于获取SQLSERVER数据库中所有表,首先第一步引有SQLDMO.dll 找到文件路径: C:\Program   Files\Microsoft   SQL   Server\80\Tools\ ...

  3. 获取sqlserver数据库中所有库、表、字段名的方法

    获取sqlserver数据库中所有库.表.字段名的方法 2009年03月12日 星期四 下午 12:51 1.获取所有数据库名: SELECT Name FROM Master..SysDatabas ...

  4. sqlserver数据库中清空日志文件

    sqlserver数据库中清空日志文件,清空之后,日志文件仅为1MB.长久以来都在使用,这里贴出来给大家分享一下. 在查询分析器中完成,操作方法如下: DUMP TRANSACTION DataBas ...

  5. redis和sqlserver数据同步_SQLServer数据库之redis数据库的数据导入到SQLServer数据库中...

    本文主要向大家介绍了SQLServer数据库之redis数据库的数据导入到SQLServer数据库中,通过具体的内容向大家展现,希望对大家学习SQLServer数据库有所帮助. #!/usr/bin/ ...

  6. oracle数据库中批量把一张表里面的数据插入到不同的表中的方法

    oracle数据库中批量把一张表里面的数据插入到不同的表中的方法(insert first into | insert all into) 准备环境 1.oracle数据库自带的scott下的用户表 ...

  7. oracle写excel文件,ORACLE-将oracle数据库中数据写入excel文件

    ORACLE-将oracle数据库中数据写入excel文件主要实现思路: 1.声明一个纪录,用来存储导出的数据: 2.使用游标取数据到纪录中: 3.使用utl_file将纪录中的数据写入excel文件 ...

  8. sqlserver根据字段查表_查找sqlserver数据库中,查询某值所表名和字段名

    有时候我们想通过一个值知道这个值来自数据库的哪个表以及哪个字段,通过一个存储过程实现的.只需要传入一个想要查找的值,即可查询出这个值所在的表和字段名. 前提是要将这个存储过程放在所查询的数据库. CR ...

  9. 向sqlserver数据库中传递类似数组的参数解决办法

    向sqlserver数据库中传递类似数组的参数解决办法 关于sqlserver数据库存储过程传递varchar类型参数(后端给出参数格式 '1,2,3').但是查询始终没有结果,但是直接写在语句中确实 ...

最新文章

  1. 每天学一点flash (20) flash cs3.0 外部加载图片
  2. Cissp-【第3章 安全工程】-2021-2-24(322页-376页)
  3. java gb13000 ucs2_采用GB 13000的UCS-2进行存储的文件怎么转换
  4. iOS最为简单时间轴(GZTimeLine)
  5. dubbo protocol port 消费者端_Dubbo 优雅停机演进之路
  6. python设置环境变量_小白Python进行中
  7. 降维系列之 LE 拉普拉斯特征映射
  8. mysql集群系统_轻松构建Mysql高可用集群系统
  9. 移动端H5游戏开发之(移动端尺寸基础知识)
  10. word多级目录设置和自动生成目录
  11. e470c拆机图解全拆 thinkpad_THINKPAD e470硬盘拆解教程是?
  12. 2022,一名85后程序猿之感慨,加油
  13. 2021小结暨2022打脸计划
  14. 简约至上设计书读后感
  15. FTDI FTD2XX 驱动学习笔记(一)
  16. 在linux中连接mysql数据库服务器_Linux下连接Mysql服务器的方式
  17. 龙翔集团牵头起草全国首个月子中心服务等级划分团体标准开始实施
  18. KTorrent for KDE 4 已抵达
  19. 岩土工程勘察报告毕业设计论文
  20. ADSafe3.5.4.721超精简汇编修改启动无提示爽歪歪直接退出版

热门文章

  1. 转换固态+机械硬盘分区表格式为GPT,UEFI启动,重装WIN10+Ubuntu18.04双系统
  2. CentOS常用zip压缩和解压缩命令
  3. ro素质点模拟器_仙境传说RO:最具人气职业猎人成长攻略手册
  4. SQL Server的数据库文件保存在哪儿?
  5. 如何找到google主题的壁纸
  6. 什么是SQL注入式攻击!如何防范SQL注入式攻击?
  7. pmx转fbx的具体步骤
  8. html —— table 标签 与 display:table 样式
  9. 压缩文件已损坏如何修复
  10. WordPress 不修改代码通过sql语句修改数据库批量增加文章阅读量