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. mysql 5.6 binlog组提交1

    [MySQL 5.6] MySQL 5.6 group commit 性能测试及内部实现流程   尽管Mariadb以及Facebook在long long time ago就fix掉了这个臭名昭著的 ...

  2. Jetty学习(一)

           最近做一个项目,需要动态添加与移除servlet容器的http端口,并且启动都是嵌入式的.因此,果断选择了Jetty.        在模块化方面,Jetty是做的相当给力的一个容器,对 ...

  3. Aggregating local features for Image Retrieval

    Josef和Andrew在2003年的ICCV上发表的论文[10]中,将文档检索的方法借鉴到了视频中的对象检测中.他们首先将图像的特征描述类比成单词,并建立了基于SIFT特征的vusual word ...

  4. debian root用户在shell下如何能够使用颜色

    转载:http://hi.baidu.com/aivera/item/f31c4a590ef72609e6c4a596 编辑 /root/.bashrc 这个文件, 把里面这几行前面的#号去掉就可以了 ...

  5. IIS 之 添加绑定域名 或 设置输入IP直接访问网站

    1.打开IIS,右键站点 → 编辑绑定,弹出“网站绑定”窗口,如下图:   2.点击“添加”,弹出“添加网站绑定”窗口,如下图:   注意:若想输入 IP 地址直接访问,则可以有以下两种设置任一均可: ...

  6. linux:ifconfig命令

    许多windows非常熟悉ipconfig命令行工具,它被用来获取网络接口配置信息并对此进行修改.Linux系统拥有一个类似的工具,也就是ifconfig(interfaces config).通常需 ...

  7. 为Mono安装MySql连接驱动

    为Mono安装MySql连接驱动(转) 2013 年 1 月 24 日.NETmono.MySql DOTNET and Mono by default only support database c ...

  8. storyBoard中的Segue跳转

    //———————————————--------------在不确定的Segue跳转-----------------------------------   多个按钮指向要跳转的视图 1.在一个恰 ...

  9. android源码编译过程

    1.下载好android源码包. 2.装好vm,ubuntu(如果能在实体机装linux更好). 3.安装所需要的deb包 在终端执行如下命令: sudo apt-get install flex b ...

  10. 高效Count

    SQL Server快速查询某张表的当前行数   传统做法可能是select count(1) 但是往往会比较慢.推荐如下做法: SELECT ISNULL(MAX(rowcnt), 0) Curre ...