首页 > 数据库 >.net批量插入到oracle数据库--三种方式对比,亲测

.net批量插入到oracle数据库--三种方式对比,亲测

时间:2023-12-12 17:33:42浏览次数:35  
标签:count -- cmd int oracle new net dt conn

根据上篇的内容,简单测试了三种方式的对比,需要使用的,请自行根据需求优化。。。

上篇文字网址:https://www.cnblogs.com/ggll611928/p/17897005.html

 

1、创建测试表

CREATE TABLE T_TEST
(
  ID      NUMBER(9) not null,
  NAME    NVARCHAR2(30) not null,
  AGE     NUMBER(2),
  CREATEDATE DATE,
  REMARK  NVARCHAR2(50)
);
COMMENT ON COLUMN T_TEST.ID IS '测试编号';
COMMENT ON COLUMN T_TEST.NAME IS '测试姓名';
COMMENT ON COLUMN T_TEST.AGE IS '创建时间';
COMMENT ON COLUMN T_TEST.CREATEDATE IS '测试年龄';
COMMENT ON COLUMN T_TEST.REMARK IS '测试描述';

ALTER TABLE T_TEST ADD CONSTRAINT PK_T_TEST PRIMARY KEY (ID);

 

2、创建数据源

使用DataTable,模拟数据源

        /// <summary>
        /// 获取测试数据源
        /// </summary>
        /// <returns></returns>
        public DataTable GetTestTable(int type)
        {
            //创建数据源
            DataTable dt = new DataTable("t_test");
            dt.Columns.Add("id", typeof(int));
            dt.Columns.Add("name", typeof(string));
            dt.Columns.Add("age", typeof(int));
            dt.Columns.Add("createdate", typeof(DateTime));
             
            int i, k;
            if (type == 1)
            {
                i = 1;
                k = 100000;
            }
            else if (type == 2)
            {
                i = 100001;
                k = 200000;
            }
            else
            {
                i = 200001;
                k = 300000;
            }

            //添加数据到 DataTable  
            for (; i <= k; i++)
            { 
                DataRow row = dt.NewRow();
                row["id"] = i;
                row["name"] = i+ "-" + i;
                row["age"] = 18;
                row["createdate"] = DateTime.Now;
                dt.Rows.Add(row);
            }
            return dt;
        }

 

3、编写三种方式

3.1 方式一:常规方式

        /// <summary>
        /// 批量处理插入数据,使用常规方式
        /// </summary>
        /// <param name="dt">数据源</param>
        /// <returns></returns>
        public int Insert(DataTable dt)
        {
            int count = 0;
            string conString = orcHelper.GetConn();
            using (OracleConnection conn = new OracleConnection(conString))
            {
                if (conn.State != ConnectionState.Open)
                {
                    conn.Open();
                }
                using (OracleTransaction transaction = conn.BeginTransaction())
                {
                    using (OracleCommand cmd = conn.CreateCommand())
                    { 
                        cmd.Transaction = transaction;
                        string sql = @"insert into t_test(id, name, age, createdate) values(:id, :name, :age, :createdate)";
                        foreach (DataRow dw in dt.Rows)
                        {
                            OracleParameter[] parametersList = new OracleParameter[]
                            {
                                new OracleParameter(":id", int.Parse(dw["id"].ToString())),
                                new OracleParameter(":name", dw["name"].ToString()),
                                new OracleParameter(":age",int.Parse(dw["age"].ToString())),
                                new OracleParameter(":createdate",DateTime.Parse(dw["createdate"].ToString())),
                            };
                            cmd.CommandText = sql;
                            cmd.CommandType = CommandType.Text;
                            cmd.Parameters.Clear();
                            cmd.Parameters.AddRange(parametersList);

                            try
                            {
                                count = cmd.ExecuteNonQuery();
                                if (count < 0) { 
                                    transaction.Rollback();
                                    return count;
                                }
                            }
                            catch (Exception)
                            {
                                transaction.Rollback();
                                return count;
                            }
                        }
                        transaction.Commit();
                        return count;
                    }
                }
            }
        }

 

3.2 方式二:使用OracleBulkCopy

        /// <summary>
        /// 批量处理插入数据,使用OracleBulkCopy
        /// </summary>
        /// <param name="dt">数据源</param> 
        public bool InsertOracleBulkCopy(DataTable dt)
        { 
            string conString = orcHelper.GetConn();
            using (OracleConnection conn = new OracleConnection(conString))
            {
                if (conn.State != ConnectionState.Open)
                {
                    conn.Open();
                }

                using (OracleTransaction transaction = conn.BeginTransaction())
                {
                    //创建 OracleBulkCopy 对象,并指定数据库连接信息 
                    using (OracleBulkCopy bulkCopy = new OracleBulkCopy(conn))
                    { 
                        //数据库表名称
                        bulkCopy.DestinationTableName = dt.TableName;      
                        //指定批量插入的行数 
                        bulkCopy.BatchSize = dt.Rows.Count;             

                        //指定 DataTable 和数据表的列名映射关系
                        for (int i = 0; i < dt.Columns.Count; i++)
                        {
                            bulkCopy.ColumnMappings.Add(dt.Columns[i].ColumnName, dt.Columns[i].ColumnName);
                        }
                        try
                        {  
                            //将数据源添加到 OracleBulkCopy 对象中
                            bulkCopy.WriteToServer(dt);              
                            transaction.Commit();
                            return true; 
                        }
                        catch (Exception)
                        {
                            transaction.Rollback();
                            return false; 
                        }
                    }
                } 
            } 
        }

 

3.3 方式三:使用ArrayBind

        /// <summary>
        /// 批量处理插入数据,使用ArrayBind
        /// <param name="dt">数据源</param>
        /// </summary>
        public int InsertArrayBind(DataTable dt)
        {
            string conString = orcHelper.GetConn();
            using (OracleConnection conn = new OracleConnection(conString))
            {
                if (conn.State != ConnectionState.Open)
                {
                    conn.Open();
                }

                using (OracleTransaction transaction = conn.BeginTransaction())
                {
                    int recordCount = dt.Rows.Count, i = 0, count = 0;

                    using (OracleCommand cmd = conn.CreateCommand())
                    {
                        cmd.Transaction = transaction;
                        cmd.CommandText = "insert into t_test(id, name, age, createdate) values(:id, :name, :age, :createdate)";
                        //指定单次需要处理的条数
                        cmd.ArrayBindCount = recordCount;
                        int[] p_col1 = new int[recordCount];
                        string[] p_col2 = new string[recordCount];
                        int[] p_col3 = new int[recordCount];
                        DateTime[] p_col4 = new DateTime[recordCount];

                        cmd.Parameters.Add(new OracleParameter("id", OracleDbType.Int32, p_col1, ParameterDirection.Input));
                        cmd.Parameters.Add(new OracleParameter("name", OracleDbType.Varchar2, p_col2, ParameterDirection.Input));
                        cmd.Parameters.Add(new OracleParameter("age", OracleDbType.Int32, p_col3, ParameterDirection.Input));
                        cmd.Parameters.Add(new OracleParameter("createdate", OracleDbType.Date, p_col4, ParameterDirection.Input));

                        foreach (DataRow dr in dt.Rows)
                        {
                            p_col1[i] = Convert.ToInt32(dr["id"].ToString());
                            p_col2[i] = dr["name"].ToString();
                            p_col3[i] = Convert.ToInt32(dr["age"].ToString());
                            p_col4[i] = Convert.ToDateTime(dr["createdate"].ToString());
                            i++;
                        }

                        try
                        {  
                            count = cmd.ExecuteNonQuery();
                            if (count > 0) { transaction.Commit(); } 
                        }
                        catch (Exception)
                        {
                            transaction.Rollback(); 
                        } 
                        return count;
                    }
                }
            }
        }

 

4、调用三种方式,进行测试

只需调用下面的方法,即可测试三种方式的对比效果

        /// <summary>
        /// 测试批量插入
        /// </summary>
        private void TestInsert()
        { 
            int count;
            long totalTime;
            string message = "", result;
            var sw = new Stopwatch();
             
            #region 1、使用常规方式进行批量添加数据
            DataTable dataTable = sysService.GetTestTable(1);
            message += "三种方式对比,每种循环的总记录数:" + dataTable.Rows.Count + "\n";

            sw.Start();
            count = sysService.Insert(dataTable);
            sw.Stop();
            totalTime = sw.ElapsedMilliseconds; 
            result = count > 0 ? "成功" : "失败";
            message += "\n方式一:常规方式--" + result + ",  使用总时间:" + totalTime ;

            #endregion

            #region 2、使用OracleBulkCopy进行批量添加数据 
            dataTable = sysService.GetTestTable(2); 

            sw.Start();
            bool isOk = sysService.InsertOracleBulkCopy(dataTable);
            sw.Stop();
            totalTime = sw.ElapsedMilliseconds; 
            result = isOk ? "成功" : "失败";
            message += "\n方式二:OracleBulkCopy--" + result + ",  使用总时间:" + totalTime ;

            #endregion

            #region 3、使用ArrayBind进行批量添加数据
            dataTable = sysService.GetTestTable(3); 

            sw.Start();
            count = sysService.InsertArrayBind(dataTable);
            sw.Stop();
            totalTime = sw.ElapsedMilliseconds; 
            result = count>0 ? "成功" : "失败";
            message += "\n方式三:ArrayBind--" + result + ",  使用总时间:" + totalTime;

            #endregion
             
            MessageBox.Show(message, "GrowlMsg"); 
        }

 

5、运行结果

 

执行完后,数据库中该表的总条数

 

 

重点注意:数据的完整性及合理性,如主键数据必须唯一,日期必须是日期格式等。

标签:count,--,cmd,int,oracle,new,net,dt,conn
From: https://www.cnblogs.com/ggll611928/p/17897390.html

相关文章

  • Mysql count(*)、count(1)、count(主键)、count(普通字段) 性能对比
    count(*):底层会转化为count(0)来处理,默认横向扫描聚集索引树,如果有二级索引就扫描二级索引树(因为二级索引树更小,扫描成本低),扫描到一行记录之后,将该记录返回给Server层,由于参数是0,不为NULL,所以不需要读取记录中的任何字段,直接将 count变量加1count(1):处理......
  • 使用 AWS Go SDK 读取审计日志(CloudTrail)
    背景公司的海外业务需要将云上的操作读取到内部的日志文件中,永久保存,供内部审计使用。由于之前没有用过AWS相关的SDK,在使用过程中也遇到一些困难,这里记录一下,并且总结一下过程。代码快速开始代码参考地址:https://github.com/awsdocs/aws-doc-sdk-examples/blob/main/go/examp......
  • MySQL 忘记密码解决方案
    数据库版本5.7.301配置文件中去掉认证编辑my.cnf服务配置文件 [mysqld]段段中加入skip-grant-tables语句2本地root账号免密登陆[root@mysql0006bin]#./mysql-uroot-pWelcometotheMySQLmonitor.Commandsendwith;or\g.YourMySQLconnectionidis3Serverversi......
  • 可视化监控云平台/智能监控EasyCVR如何使用脚本创建ramdisk挂载并在ramdisk中临时运行
    视频云存储/安防监控EasyCVR视频汇聚平台基于云边端智能协同,支持海量视频的轻量化接入与汇聚、转码与处理、全网智能分发、视频集中存储等。安防管理视频平台EasyCVR拓展性强,视频能力丰富,具体可实现视频监控直播、视频轮播、视频录像、云存储、回放与检索、智能告警、服务器集群、......
  • 无涯教程-MFC - Tree Control函数
    TreeViewControl是一个窗口,其中显示项目的层次结构列表,例如文档中的标题,索引中的条目或磁盘上的文件和目录,每个项目都包含一个标签和一个可选的位图图像,并且每个项目都可以具有与其相关联的子项目列表,通过单击一个项目,用户可以展开和折叠子项目的关联列表,它由CTreeCtrl类表......
  • JSSDK获取signature签名,史上最全,没有之一
    微信公众号JSSDK获取signature签名,史上最全,没有之一1.操作流程1、通过appId和appSecret获取access_token;2、使用access_token获取jsapi_ticket;3、用时间戳、随机数、jsapi_ticket和要访问的url按照签名算法拼接字符串;4、对第三步得到的字符串进行SHA1加密,得到签名。2.上代码获取a......
  • 恒创科技:是什么导致网络服务器变慢?(服务器请求超时)
    ​服务器之间的网络请求和响应的速度可能因多种因素而有很大差异。这个问题没有一刀切的答案,因为这取决于具体情况和网络通信的性质。有几个因素可能会导致网络服务器速度缓慢,包括:硬件问题:服务器硬件本身可能已经故障或资源不足,这可能包括处理器核心或线程不足、内......
  • Linux安装cuda环境
    安装cuda驱动时需要先卸载开源的cuda驱动参看是否安装了开源驱动nouveaulsmod|grepnouveau关闭cat<<EOF|sudotee/etc/modprobe.d/blacklist-nouveau.confblacklistnouveauoptionsnouveaumodeset=0EOF重新生成内核initramfssudoupdate-initramfs-u重启......
  • pytest 如何测试函数中抛出的异常
    一般Python中异常可以用raise来抛出,此时单测中想要测试错误用例是否触发异常了,可以用pytest中的 withpytest.raises(xxx)如下:importpytestimportunittestclassInfo(object):"""infoclass"""def__init__(self,name):"""......
  • 可视化监控云平台/智能监控EasyCVR如何使用脚本创建ramdisk挂载并在ramdisk中临时运行
    视频云存储/安防监控EasyCVR视频汇聚平台基于云边端智能协同,支持海量视频的轻量化接入与汇聚、转码与处理、全网智能分发、视频集中存储等。安防管理视频平台EasyCVR拓展性强,视频能力丰富,具体可实现视频监控直播、视频轮播、视频录像、云存储、回放与检索、智能告警、服务器集群、......