C# 海量数据瞬间插入到数据库的方法

当我们在数据库中进行大量的数据追加时,是不是经常因为数据量过大而苦恼呢?
而所谓的海量数据,一般也是上万级的数据,比如我们要添加一百万条数据,应该如何提高它的效率呢?

Oracle数据库:

普通肉垫式

什么叫批量插入呢,就是一次性插入一批数据,我们可以把这批数据理解为一个大的数组,而这些全部只通过一个SQL来实现,而在传统方式下,需要调用很多次的SQL才可以完成,这就是著名的“数组绑定”的功能。我们先来看一下传统方式下,插入多行记录的操作方式:

//设置一个数据库的连接串,
string connectStr = "User Id=scott;Password=tiger;Data Source=";
OracleConnection conn = new OracleConnection(connectStr);
OracleCommand command = new OracleCommand();
command.Connection = conn;
conn.Open();
//通过循环写入大量的数据,这种方法显然是肉垫
for (int i = ; i < recc; i++)
{
string sql = "insert into dept values(" + i.ToString() + "," + i.ToString() + "," + i.ToString() + ")";
command.CommandText = sql;
command.ExecuteNonQuery();
}

带事务的栗子:

string result;
//创建连接
var conn = new OracleConnection(_connectStr);
conn.Open();
var tran = conn.BeginTransaction(); //事务
try
{
CreateTable(jiFenZhuiSuGuanXis.Select(info => info.TableGroup).Distinct().ToList()); //创建数据库表 带有分表要求
//创建Command 并循环插入数据
var command = conn.CreateCommand();
foreach (var guanXi in jiFenZhuiSuGuanXis)
{
//插入
var insertStr = string.Format(
"insert into {5} values('{0}','{1}','{2}','{3}','{4}')", "","","","","");
command.CommandText = insertStr;
command.ExecuteNonQuery();
}
tran.Commit();
result = "成功";
}
catch (OracleException ex)
{
tran.Rollback();
result = "出现错误。\n"+ex.Message;
LogHelper.WriteLog("UpLoad.OracleException捕获异常。\n", ex);
}
catch (Exception ex)
{
result = "出现错误。\n" + ex.Message;
LogHelper.WriteLog("UpLoad.Exception捕获异常。\n", ex);
}
finally
{
if (conn.State == ConnectionState.Open)
conn.Close();
}
return result;

使用ODP特性

//设置一个数据库的连接串
string connectStr = "User Id=scott;Password=tiger;Data Source=";
OracleConnection conn = new OracleConnection(connectStr);
OracleCommand command = new OracleCommand();
command.Connection = conn;
//到此为止,还都是我们熟悉的代码,下面就要开始喽
//这个参数需要指定每次批插入的记录数
command.ArrayBindCount = recc;
//在这个命令行中,用到了参数,参数我们很熟悉,但是这个参数在传值的时候
//用到的是数组,而不是单个的值,这就是它独特的地方
command.CommandText = "insert into dept values(:deptno, :deptname, :loc)";
conn.Open();
//下面定义几个数组,分别表示三个字段,数组的长度由参数直接给出
int[] deptNo = new int[recc];
string[] dname = new string[recc];
string[] loc = new string[recc];
// 为了传递参数,不可避免的要使用参数,下面会连续定义三个
// 从名称可以直接看出每个参数的含义,不在每个解释了
OracleParameter deptNoParam = new OracleParameter("deptno", OracleDbType.Int32);
deptNoParam.Direction = ParameterDirection.Input;
deptNoParam.Value = deptNo;
command.Parameters.Add(deptNoParam);
OracleParameter deptNameParam = new OracleParameter("deptname", OracleDbType.Varchar2);
deptNameParam.Direction = ParameterDirection.Input;
deptNameParam.Value = dname; command.Parameters.Add(deptNameParam);
OracleParameter deptLocParam = new OracleParameter("loc", OracleDbType.Varchar2);
deptLocParam.Direction = ParameterDirection.Input;
deptLocParam.Value = loc;
command.Parameters.Add(deptLocParam);
//在下面的循环中,先把数组定义好,而不是像上面那样直接生成SQL
for (int i = ; i < recc; i++)
{
deptNo[i] = i;
dname[i] = i.ToString();
loc[i] = i.ToString();
}
//这个调用将把参数数组传进SQL,同时写入数据库
command.ExecuteNonQuery();

如果插入多张表格的数据 Command 需要重新new

string result;
//创建连接
var conn = new OracleConnection(_connectStr);
conn.Open();
var tran = conn.BeginTransaction(); //事务
try
{
//创建数据库表 分表要求
CreateTable(jiFenZhuiSuGuanXis.Select(info => info.TableGroup).Distinct().ToList());
//根据分表名称 将数据分组
var dataTableGroup = jiFenZhuiSuGuanXis.GroupBy(j => j.TableGroup);
foreach (var group in dataTableGroup)
{
var command = conn.CreateCommand(); //创建Command
command.ArrayBindCount = group.Count(); //插入数量
//插入语句
command.CommandText = string.Format(
"insert into {0} values(:jiid,:productcode,:productspec,:zhuisucode,:jifencode)",
group.Key.ToUpper());
#region 定义传递参数
var idParam = new string[group.Count()];
var productCodeParam = new string[group.Count()];
var productSpecParam = new string[group.Count()];
var zhuisucodeParam = new string[group.Count()];
var jifencodeParam = new string[group.Count()];
//定义传递参数
command.Parameters.AddRange(new[]
{
new OracleParameter("jiid", OracleDbType.NVarchar2)
{
Direction = ParameterDirection.Input,
Value = idParam
},
new OracleParameter("productcode", OracleDbType.NVarchar2)
{
Direction = ParameterDirection.Input,
Value = productCodeParam
},
new OracleParameter("productspec", OracleDbType.NVarchar2)
{
Direction = ParameterDirection.Input,
Value = productSpecParam
},
new OracleParameter("zhuisucode", OracleDbType.NVarchar2)
{
Direction = ParameterDirection.Input,
Value = zhuisucodeParam
},
new OracleParameter("jifencode", OracleDbType.NVarchar2)
{
Direction = ParameterDirection.Input,
Value = jifencodeParam
}
}
);
#endregion
#region 参数赋值
var i = ;
foreach (var xi in group)
{
idParam[i] = xi.Id; //ID参数
productCodeParam[i] = xi.ProductCode; //productcode参数
productSpecParam[i] = xi.ProductSpec; //productspec参数
zhuisucodeParam[i] = xi.ZhuiSuCode; //zhuisucode参数
jifencodeParam[i] = xi.JiFenCode; //JiFenCode参数
i++;
}
#endregion
command.ExecuteNonQuery(); //执行
}
tran.Commit();
result = "成功";
}
catch (OracleException ex)
{
tran.Rollback();
result = "出现错误。\n" + ex.Message;
LogHelper.WriteLog("UpLoadOdp.OracleException捕获异常。\n", ex);
}
catch (Exception ex)
{
result = "出现错误。\n" + ex.Message;
LogHelper.WriteLog("UpLoadOdp.Exception捕获异常。\n", ex);
}
finally
{
if (conn.State == ConnectionState.Open)
conn.Close();
}
return result;

C# Oracle海量数据瞬间插入到数据库的方法的更多相关文章

  1. C# 海量数据瞬间插入到数据库的方法

    C# 海量数据瞬间插入到数据库的方法 当我们在数据库中进行大量的数据追加时,是不是经常因为数据量过大而苦恼呢?而所谓的海量数据,一般也是上万级的数据,比如我们要添加一百万条数据,应该如何提高它的效率呢 ...

  2. Oracle shutdown immediate无法关闭数据库解决方法

    在测试服务器上使用shutdown immediate命令关闭数据库时,长时间无法关闭数据库,如下所示 1: [oracle@DB-Server admin]$ sqlplus / as sysdba ...

  3. oracle insert into 插入多组数据方法总结

    网上好多oracle 的文章,多是以oracle开头,内容确实其他sql,一幅气死人不偿命的嘴脸着实让人难受. 今天就更新点oracle 使用insert into插入数据的方式: 1.oracle ...

  4. .net批量插入SqlServer数据库的方法:

    using System;using System.Collections.Generic;using System.Configuration;using System.Data;using Sys ...

  5. C# OracleBulkCopy 批量插入oracle数据库的方法

    只有安装了oracle 11G客户端的机器上才可以用,要用到ODP.NET组件中的oracleDataAccess.DLL,命名空间引用为Oracle.DataAccess.Client; 引用:Or ...

  6. Excel导入数据库百万级数据瞬间插入

    Excel导入数据库百万级数据瞬间插入 百万级别,瞬间,有点吊哇

  7. 批量插入数据, 将DataTable里的数据批量写入数据库的方法

    大量数据导入操作, 也就是直接将DataTable里的内容写入到数据库 通用方法: 拼接Insert语句, 好土鳖 1. MS Sql Server:   使用SqlBulkCopy 2. MySql ...

  8. Hbase与Oracle比较(列式数据库与行式数据库)

    Hbase与Oracle比较(列式数据库与行式数据库) 1 主要区别 Hbase适合大量插入同时又有读的情况 Hbase的瓶颈是硬盘传输速度,Oracle的瓶颈是硬盘寻道时间.   Hbase本质上只 ...

  9. Oracle和MySQL插入时获取主键

    这里只写selectKey方法的 一,Oracle数据库中的写法 order="BEFORE"因为oracle中需要先从序列获取值,然后将值作为主键插入到数据库中 <sele ...

随机推荐

  1. StarlingMVC Framework中文教程

    配置与开始 将Starling项目配置为StarlingMVC项目,仅需几行代码.在继承于starling.display.Sprite的起始类里,创建一个StarlingMVC的实例,并传递给它三个 ...

  2. MySQL 5.7: Enhanced Multi-threaded slaves

    http://geek.rohitkalhans.com/2013/09/enhancedMTS-deepdive.html   科学上网 Introduction Re-applying binar ...

  3. dubbo-RPC学习(一)自定义配置

    在dubbo的基础上实现异步调用的时候,因为需要支持回调的“重试间隔时间”与“重试次数”等属性.因此,需要扩展dubbo.xsd,需要添加新的属性来支持这种扩展. dubbo 的xsd是基于sprin ...

  4. C#_自动化测试 (四) 自动卸载软件

    在平常的测试工作中,经常要安装软件,卸载软件,  即繁琐又累.  安装和卸载完全可以做成自动化. 安装软件我们可以通过自动化框架,自动点击Next,来自动安装.  卸载软件我们可以通过msiexec命 ...

  5. python实现之极简stack和queue

    用python实现一个极简的stack和queue,那是so easy的事情了,简洁易懂,适合小白~ 直接上代码吧: node: class LinkNode: def __init__( self, ...

  6. LINUX命令之ETHTOOL用法详解

    转载:http://crazyming.blog.51cto.com/1048571/738022 debian 下安装: sudo apt-get install ethtool 或者下载源码编译: ...

  7. Android XML文件布局各个属性详解

    第一常用类:属性值为true或false android:layout_centerHrizontal 水平居中 android:layout_centerVertical 垂直居中 android: ...

  8. Android基本控件之RadioGroup

    我们在手机上经常看到一堆选项,但是我们只能选择一个,那么在Android中,这个控件就叫做RadioButton,也就是单选按钮的意思,他们之所以能够达到只能选择一个的效果,是因为有一个RadioGr ...

  9. iOS: 属性声明strong和retain竟然不一样

    今天和同事在处理一处用strong声明的Block属性引发的问题时偶然发现的.在诸多教程中都会讲到:声明属性时用strong或者retain效果是一样的(貌似更多开发者更倾向于用strong).不过在 ...

  10. A+B Problem(V)

    描述 做了A+B Problem之后,Yougth感觉太简单了,于是他想让你求出两个数反转后相加的值.帮帮他吧 输入 有多组测试数据.每组包括两个数m和n,数据保证int范围,当m和n同时为0是表示输 ...