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. Oracle数据库的导入与导出

    导出 在命令行输入"exp",回车即可访问指定的数据库, 我这里需要访问远程的数据库,所以带上了IP.端口等一些参数,具体的参数详情可以输入"exp -help" ...

  2. 百度API_Demo

    package com.test.www; import java.io.BufferedReader; import java.io.IOException; import java.io.Inpu ...

  3. java面试笔试谈

    例一: public class Inc { public static void main(String[] args) { Inc inc=new Inc(); int i=5; inc.ferm ...

  4. BootStrap2学习日记6---代码

    &lt:表示“<” &gt:表示“>” 在BootStrap中标记代码的标签使用<code>,标记代码块使用<pre>(里面的代码特殊标签必须转义) ...

  5. AspxGridView整理文档【转】

    ASPxGridView属性:概述设置(Settings) <Settings GridLines="Vertical" : 网格样式 Vertical, Both, Non ...

  6. 分享一个java线程专栏

    专栏 : java线程基础 转载自 http://blog.csdn.net/column/details/yinwenjiethread.html 专栏内容: 1.线程基础:线程(1)--操作系统和 ...

  7. Volly的使用及图片错位优化

    listview显示数据,利用第三方jar包Volley下的ImageLoader加载图片时,当数据类型不一致,布局复用的时候会出现图片错位,因此需要自定义IMymageLoader实现ImageLo ...

  8. 以前写过的一些oracle语句

    这下以后用起来就方便了.可算是找到了 Orcl 数据库服务 启动项: OracleDBConsoleorcl OracleOraDb10g_home1iSQL*Plus OracleOraDb10g_ ...

  9. Linux kill -9 和 kill -15 的区别

    “我的天呀!”,网页编辑没有自动保存草稿的功能.害的我昨天写的东西都没有了.算了,不计较这些了.反正也没写多少. 嘻嘻. 大家对kill -9 肯定非常熟悉,在工作中也经常用到.特别是你去重启tomc ...

  10. Mac 10.9 自带apache2虚拟目录设置

    花了好几天时间做这个事,终于成功,把正确的做法记录一下. 如果是第一次使用apache,可以先执行sudo apachectl start,然后在浏览器里打开http://localhost看看效果, ...