.net批量插入到oracle数据库

您所在的位置:网站首页 数据库批量入库 .net批量插入到oracle数据库

.net批量插入到oracle数据库

2024-07-16 16:41| 来源: 网络整理| 查看: 265

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

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

 

三种方式:

1、常规方式,通过sql语句循环执行 

2、使用OracleBulkCopy

3、使用ArrayBind

 

后面:增加了扩展,使用存储过程+  ArrayBind

具体步骤如下:

 

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,模拟数据源

/// /// 获取测试数据源 /// /// 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 0) { transaction.Commit(); } } catch (Exception) { transaction.Rollback(); } return count; } } } }

 

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

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

/// /// 测试批量插入 /// 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、运行结果

 

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

 

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

 

6、扩展:存储过程

使用存储过程 + ArrayBind,批量修改数据

 

6.1 创建测试用的存储过程

主要实现修改数据

CREATE OR REPLACE PROCEDURE p_test_yy( p_Id IN t_test.ID%TYPE, p_Name IN t_test.NAME%type, p_ErrCode OUT NUMBER, p_ErrText OUT VARCHAR2 ) AS v_cnt NUMBER; begin select count(*) into v_cnt from t_test where id = p_Id; if v_cnt is null or v_cnt = 0 then p_ErrCode := -1; p_ErrText :='编号:'||p_Id||'-信息不存在!'; return; end if; -- 模拟错误数据 if p_Id = 10 or p_Id = 11 then p_ErrCode := -1; p_ErrText :='编号:'||p_Id||'-重复!'; return; end if; update t_test set createdate=sysdate where id = p_Id; p_ErrCode := p_Id; p_ErrText := '编号:'||p_Id||'-修改日期成功!'; commit; exception when others then p_ErrCode := -ABS(sqlcode); P_ErrText := '发生错误,错误信息为:'||SUBSTR(SQLERRM, 1, 200); rollback; end p_test_yy;

 

6.2 重要代码 /// /// 批量处理数据,使用存储过程 + ArrayBind /// 数据源 /// public int InsertArrayBindProcedure(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, count = 0; using (OracleCommand cmd = conn.CreateCommand()) { cmd.Transaction = transaction; cmd.CommandText = "p_test_yy"; cmd.BindByName = true; cmd.CommandType = CommandType.StoredProcedure; //指定单次需要处理的条数 cmd.ArrayBindCount = recordCount; var columnId = dt.AsEnumerable().Select(row => row.Field("id")).ToArray(); var columnName = dt.AsEnumerable().Select(row => row.Field("name")).ToArray(); cmd.Parameters.Add(new OracleParameter("p_Id", OracleDbType.Int32, columnId, ParameterDirection.Input)); cmd.Parameters.Add(new OracleParameter("p_Name", OracleDbType.Varchar2, columnName, ParameterDirection.Input)); cmd.Parameters.Add( new OracleParameter("p_ErrCode", OracleDbType.Int32, ParameterDirection.Output) { ArrayBindSize = new int[] { recordCount } }); cmd.Parameters.Add( new OracleParameter("p_ErrText", OracleDbType.Varchar2, ParameterDirection.Output) { ArrayBindSize = new int[] { recordCount } }); try { count = cmd.ExecuteNonQuery(); //正常获取p_ErrCode的全部数据 object objCode = cmd.Parameters["p_ErrCode"].Value; OracleDecimal[] oDecimalCodes = (OracleDecimal[]) objCode; //只能获取p_ErrText的第一条数据 object objText = cmd.Parameters["p_ErrText"].Value; OracleString[] oDecimalTexts = (OracleString[])objText; int codeCount = oDecimalCodes.AsEnumerable().ToList().Where(t => t < 1).Count(); if (codeCount > 0) { count = 0; transaction.Rollback(); return count; } count = oDecimalCodes.Count(); transaction.Commit(); } catch (Exception) { transaction.Rollback(); } return count; } } } }

 

6.3 调用

其中GetTestTable,在上面右介绍,此处不再说明

/// /// 测试存储过程批量处理数据 /// private void TestProcedure() { int count; long totalTime; string message = "", result; var sw = new Stopwatch(); DataTable dataTable = sysService.GetTestTable(1); message += "循环的总记录数:" + dataTable.Rows.Count + "\n"; sw.Start(); count = sysService.InsertArrayBindProcedure(dataTable); sw.Stop(); totalTime = sw.ElapsedMilliseconds; result = count > 0 ? "成功" : "失败"; message += "\n测试存储过程批量处理数据--" + result + ", 使用总时间:" + totalTime; MessageBox.Show(message, "GrowlMsg"); }

 

6.4 调试

根据下图,可以看到

存储过程返回的第一个参数p_ErrCode,可以正常获取全部数据

但是,第二个参数p_ErrText,只能获取第一条的数据

原因目前还没弄清除,有需求的自己研究。。。

故需要使用存储过程批量处理数据时,执行前一定确定数据的完整性,这样批量执行就不会出错!!!

 

 

 

 



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3