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. 获取文件属性信息之stat、fstat和lstat

    UNIX文件系统是目录和文件组成的一种层次结构.目录(directory)是一个包含许多目录项的文件,在逻辑上,可以认为每个目录项都包含一个文件名,同时还包含说明该文件属性的信息.文件属性是指文件类型 ...

  2. java_有返回值线程_提前加载例子

    package com.demo.test3; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionE ...

  3. Helpers\FastCache

    Helpers\FastCache phpFastCache is a high-performance, distributed object caching system, generic in ...

  4. maven系列之一maven安装和与IDE集成

    第一部分:maven的基本信息和安装,配置  maven是一个项目构建和管理的工具,提供了帮助管理 构建.文档.报告.依赖.scms.发布.分发的方法.可以方便的编译代码.进行依赖管理.管理二进制库等 ...

  5. Maven学习小结(六 setting.xml详解[转])

    当Maven运行过程中的各种配置,例如pom.xml,不想绑定到一个固定的project或者要分配给用户时,我们使用settings.xml中的settings元素来确定这些配置.这包含了本地仓库位置 ...

  6. Java设计模式11:常用设计模式之代理模式(结构型模式)

    1. Java之代理模式(Proxy Pattern) (1)概述: 代理模式的作用是:为其他对象提供一种代理以控制对这个对象的访问. 在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理对象 ...

  7. Android(java)学习笔记88:TextView属性大全

    TextView属性大全: android:autoLink       设置是否当文本为URL链接/email/电话号码/map时,文本显示为可点击的链接.可选值(none/web/email/ph ...

  8. myEclipse6.5与数据库(SQL Server2008)连接遇到的问题(自己总结的干货)<用SSH框架的时候,用servlet+javabean+jsp的时候>

    昨天因为学习SSH框架的搭建,时隔一年又重新遇到了myEclipse连接数据库的问题.废话不多说,上干货 (以下全部按照我遇到的问题的顺序,也就是没有顺序,就是任性) 请注意:这是在myEclipse ...

  9. java.lang.IllegalArgumentException: Service Intent must be explicit: Intent

    在Activity中启动Service的时候报错: 服务意图必须是显性声明. 这是为了防止造成冲突(i.e. 有多个Service用同样的intent-filter的情况) 这是Android 5.0 ...

  10. Objective-C ,ios,iphone开发基础:picker控件详解与使用,(实现省市的二级联动)

    第一步:新建一个单视图(single view)的工程, 命名为pickerTest,不要勾选下面两个选项,第一个是新版本里面的,第二个是单元测试,现在用不着. 点击next  ->creat之 ...