首页 > 数据库 >C# Oracle海量数据瞬间插入到数据库的方法

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

时间:2023-01-08 15:00:27浏览次数:42  
标签:string C# var 海量 command ex Oracle new conn

转自:https://www.cnblogs.com/gaoyuanzhen/p/3875806.html 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 = 0; 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 = 0; 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 = 0;
        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;
复制代码

 

标签:string,C#,var,海量,command,ex,Oracle,new,conn
From: https://www.cnblogs.com/turnip/p/17034678.html

相关文章

  • @Transactional事务回滚异常:Transaction rolled back because it has been marked as
    问题描述事务设置手动回滚:TransactionAspectSupport.currentTransactionStatus().setRollbackOnly()代码需要返回比较友好的提示,但try…catch了,事务就不......
  • ENVI5.4科学数据集浏览器-FY-3C VIRR传感器的L1级数据为例-同样适用于欧空局LandCover
      ENVI科学数据集浏览器可以从HDF或NetCDF文件中建立新的ENVI栅格数据,包含数据,属性,纬度/经度信息这些元数据信息。用File>OpenAs>ScientificFormats> format菜......
  • Flutter Scaffold
    ReadaboutFlutterScaffold,itsuses,propertiesandtheimportanceofScaffoldwidgetinFlutterApps.TheScaffoldwidgetisthebaseofthescreenforasi......
  • 基于pytorch的图像训练识别
    一、准备数据集分为测试集和训练集,文件如下排放   二、开始识别数据集准备好后,即可导入到模型开始训练,运行下列代码importtimefromtorch.utils.tensorboard......
  • 【优先队列】LeetCode 23. 合并K个升序链表
    题目链接23.合并K个升序链表思路把全部结点放入优先队列中,然后再依次组成新链表代码classSolution{publicListNodemergeKLists(ListNode[]lists){......
  • Kubernetes(k8s) kubectl config常用命令
    kubectl在$HOME/.kube目录中查找一个名为config的配置文件。可以通过设置KUBECONFIG环境变量或设置--kubeconfig参数来指定其它kubeconfig文件。本文主要介绍K......
  • codeforces水题记录
    完全不需要思考https://codeforces.com/gym/104101/problem/A只要输出“fengqibisheng,yingyueerlai!”就能AC。需要一点点思考https://codeforces.com/gym/104101......
  • rayTracingTheNextWeek总结
    前言本系列总结自RayTracing:TheNextWeek,前篇为rayTracingInOneWeekend-爱莉希雅-博客园(cnblogs.com)。需要一点点的图形学基础,不懂的同学可以移至GAMES101-......
  • DevOps实战系列【第十一章】:Jenkinsfile For Docker应用案例
    个人亲自录制全套DevOps系列实战教程:​​手把手教你玩转DevOps全栈技术​​Jenkinsfile中可以直接调用docker,比如构建一个镜像、推送镜像、启动容器等,都可以在agent指令中......
  • JavaScript笔记
    变量作用域:1、全局变量:在全局作用域下声明的变量​ 在函数内部没有声明直接赋值的变量也是属于全局变量全局变量:只有浏览器关闭的时候才会销毁,比较占内存资源局部......