由于工作的原因,要使用winform来处理大量的数据,但是c#自带的System.data.OracleClient效率不是很高,在网上找了很久,找到了ODP.NET,是oracle为c#提供的。貌似从vs2010开始,微软开始推荐使用ODP.NET。效率的话,在没有索引的情况下,100万数据,不到10秒。刚开始使用的时候,由于不是很懂,所以有一些步骤是多余的,现在重新修改下。(这里是需要安装ODAC客户端)

  1.从官网上下载ODAC,如果你是32位的机器,那下载32的;64位的,就下载64的。我的win7, 64位,所以我下载的是ODAC1120320_x64,具体地址:

  64位:http://www.oracle.com/technetwork/database/windows/downloads/index-090165.html

  32位:http://www.oracle.com/technetwork/developer-tools/visual-studio/downloads/index.html

  2.解压,然后点击 setup.exe 安装,然后在这个地址:D:\app\12\product\11.2.0\client_1\odp.net\bin\2.x

  

  3.在项目中,添加引用,就可以使用了,用法跟自带的System.data.OracleClient差不多

  

  

  5.批量插入:

  1. //设置一个数据库的连接串
  2. string connectStr = "User Id=scott;Password=tiger;Data Source=";
  3. OracleConnection conn = new OracleConnection(connectStr);
  4. OracleCommand command = new OracleCommand();
  5. command.Connection = conn; //到此为止,还都是我们熟悉的代码,下面就要开始喽
  6. //这个参数需要指定每次批插入的记录数
  7. command.ArrayBindCount = recc;
  8. //在这个命令行中,用到了参数,参数我们很熟悉,但是这个参数在传值的时候
  9. //用到的是数组,而不是单个的值,这就是它独特的地方
  10. command.CommandText = "insert into dept values(:deptno, :deptname, :loc)";
  11. conn.Open();
  12. //下面定义几个数组,分别表示三个字段,数组的长度由参数直接给出
  13. int[] deptNo = new int[recc];
  14. string[] dname = new string[recc];
  15. string[] loc = new string[recc];
  16. // 为了传递参数,不可避免的要使用参数,下面会连续定义三个
  17. // 从名称可以直接看出每个参数的含义,不在每个解释了
  18. OracleParameter deptNoParam = new OracleParameter("deptno",
  19. OracleDbType.Int32);
  20. deptNoParam.Direction = ParameterDirection.Input;
  21. deptNoParam.Value = deptNo; command.Parameters.Add(deptNoParam);
  22. OracleParameter deptNameParam = new OracleParameter("deptname",
  23. OracleDbType.Varchar2);
  24. deptNameParam.Direction = ParameterDirection.Input;
  25. deptNameParam.Value = dname;
  26. command.Parameters.Add(deptNameParam);
  27. OracleParameter deptLocParam = new OracleParameter("loc", OracleDbType.Varchar2);
  28. deptLocParam.Direction = ParameterDirection.Input;
  29. deptLocParam.Value = loc;
  30. command.Parameters.Add(deptLocParam);
  31. Stopwatch sw = new Stopwatch();
  32. sw.Start();
  33. //在下面的循环中,先把数组定义好,而不是像上面那样直接生成SQL
  34. for (int i = ; i < recc; i++)
  35. {
  36. deptNo[i] = i;
  37. dname[i] = i.ToString();
  38. loc[i] = i.ToString();
  39. }
  40. //这个调用将把参数数组传进SQL,同时写入数据库
  41. command.ExecuteNonQuery();
  42. sw.Stop();
  43. System.Diagnostics.Debug.WriteLine("批量插入:" + recc.ToString()
  44. + "所占时间:" +sw.ElapsedMilliseconds.ToString());

  

  6.上面的代码太乱,给一个已经封装好的批量插入的方法:

  1. /**
  2. * 批量插入数据
  3. * @tableName 表名称
  4. * @columnRowData 键-值存储的批量数据:键是列名称,值是对应的数据集合
  5. * @conStr 连接字符串
  6. * @len 每次批处理数据的大小
  7. */
  8. public static int BatchInsert(string tableName, Dictionary<string, object> columnRowData, string conStr, int len)
  9. {
  10. if (string.IsNullOrEmpty(tableName))
  11. {
  12. throw new ArgumentException("必须指定批量插入的表名称", "tableName");
  13. }
  14.  
  15. if (columnRowData == null || columnRowData.Count < )
  16. {
  17. throw new ArgumentException("必须指定批量插入的字段名称", "columnRowData");
  18. }
  19.  
  20. int iResult = ;
  21. string[] dbColumns = columnRowData.Keys.ToArray();
  22. StringBuilder sbCmdText = new StringBuilder();
  23. if (columnRowData.Count > )
  24. {
  25. //准备插入的SQL
  26. sbCmdText.AppendFormat("INSERT INTO {0}(", tableName);
  27. sbCmdText.Append(string.Join(",", dbColumns));
  28. sbCmdText.Append(") VALUES (");
  29. sbCmdText.Append(":" + string.Join(",:", dbColumns));
  30. sbCmdText.Append(")");
  31.  
  32. using (OracleConnection conn = new OracleConnection(conStr))
  33. {
  34. using (OracleCommand cmd = conn.CreateCommand())
  35. {
  36. //绑定批处理的行数
  37. cmd.ArrayBindCount = len;
  38. cmd.BindByName = true;
  39. cmd.CommandType = CommandType.Text;
  40. cmd.CommandText = sbCmdText.ToString();
  41. cmd.CommandTimeout = ;//10分钟
  42.  
  43. //创建参数
  44. OracleParameter oraParam;
  45. List<IDbDataParameter> cacher = new List<IDbDataParameter>();
  46. OracleDbType dbType = OracleDbType.Object;
  47. foreach (string colName in dbColumns)
  48. {
  49. dbType = GetOracleDbType(columnRowData[colName]);
  50. oraParam = new OracleParameter(colName, dbType);
  51. oraParam.Direction = ParameterDirection.Input;
  52. oraParam.OracleDbTypeEx = dbType;
  53.  
  54. oraParam.Value = columnRowData[colName];
  55. cmd.Parameters.Add(oraParam);
  56. }
  57. //打开连接
  58. conn.Open();
  59.  
  60. /*执行批处理*/
  61. var trans = conn.BeginTransaction();
  62. try
  63. {
  64. cmd.Transaction = trans;
  65. iResult = cmd.ExecuteNonQuery();
  66. trans.Commit();
  67. }
  68. catch (Exception ex)
  69. {
  70. trans.Rollback();
  71. throw ex;
  72. }
  73. finally
  74. {
  75. if (conn != null) conn.Close();
  76. }
  77.  
  78. }
  79. }
  80. }
  81. return iResult;
  82. }
  83.  
  84. /**
  85. * 根据数据类型获取OracleDbType
  86. */
  87. private static OracleDbType GetOracleDbType(object value)
  88. {
  89. OracleDbType dataType = OracleDbType.Object;
  90. if (value is string[])
  91. {
  92. dataType = OracleDbType.Varchar2;
  93. }
  94. else if (value is DateTime[])
  95. {
  96. dataType = OracleDbType.TimeStamp;
  97. }
  98. else if (value is int[] || value is short[])
  99. {
  100. dataType = OracleDbType.Int32;
  101. }
  102. else if (value is long[])
  103. {
  104. dataType = OracleDbType.Int64;
  105. }
  106. else if (value is decimal[] || value is double[] || value is float[])
  107. {
  108. dataType = OracleDbType.Decimal;
  109. }
  110. else if (value is Guid[])
  111. {
  112. dataType = OracleDbType.Varchar2;
  113. }
  114. else if (value is bool[] || value is Boolean[])
  115. {
  116. dataType = OracleDbType.Byte;
  117. }
  118. else if (value is byte[])
  119. {
  120. dataType = OracleDbType.Blob;
  121. }
  122. else if (value is char[])
  123. {
  124. dataType = OracleDbType.Char;
  125. }
  126. return dataType;
  127. }

  7.调用封装的方法:

  

  8.完成。

  对于服务器上的oracle版本问题,我们的是10g,但是我用的ODP是11g的,还是可以插入数据,没什么问题,貌似可以向下兼容

C#利用ODP.NET往oracle中高效插入百万数据的更多相关文章

  1. 获得Oracle中刚插入的数据的ID(for produce)

    在sql sever中实现插入数据的自动增长是很容易的,但是在oracle数据库中实现这一操作不是很容易,同时要想在.net中实现获取新插入数据的id,而 且不会出现读错的情况,就更显得困难了,为了解 ...

  2. Oracle:高效插入大量数据经验之谈

    来源于:http://www.cnblogs.com/liwenzhen238/p/3610518.html 在很多时候,我们会需要对一个表进行插入大量的数据,并且希望在尽可能短的时间内完成该工作,这 ...

  3. Oracle中批量插入

    为了防止OracleConnection的重复打开和关闭,使用begin end:将sql语句包在里面,然后一次性执行提高插入的效率. 下面代码中要插入的数据在list集合中,如果list集合的cou ...

  4. Oracle中使用游标转换数据表中指定字段内容格式(拼音转数字)

    应用场景:将数据表TB_USER中字段NNDP的内容中为[sannanyinv]转换为[3男1女] 主要脚本:一个游标脚本+分割字符串函数+拼音转数字脚本 操作步骤如下: 1.创建类型 create ...

  5. C# 利用mysql.data 在mysql中创建数据库及数据表

    C# 利用mysql.data 在mysql中创建数据库及数据表 using System; using System.Collections.Generic; using System.Linq; ...

  6. Oracle中如何插入特殊字符: &amp;amp; 和 &amp;#39; (多种解决方案)

    Oracle中如何插入特殊字符:& 和 ' (多种解决方案)今天在导入一批数据到Oracle时,碰到了一个问题:Toad提示要给一个自定义变量AMP赋值,一开始我很纳闷,数据是一系列的Inse ...

  7. win8下在microsoft visual studio 2012利用ODP.NET连接ORACLE 12c

    老板要求我搭个ASP.NET框架,并且连接上ORACLE数据库,听起来好像挺简单的,但就是连第一步连接ORACLE我都搞了两天╮(╯▽╰)╭ 首先,项目书上要求用ORACLE 10G,可我自己的本本装 ...

  8. 在oracle中存入date类型数据遇到的问题及其解决方法(利用java.sql.date和Timestamp)

    转自:https://blog.csdn.net/ShadowerWArden/article/details/80652377 1. 使用JDBC操作Oracle数据库时,使用java.sql.Da ...

  9. oracle中的rowid和数据行的结构

    在oracle数据库系统中每一行都有一个rowid,oracle数据库系统就是利用rowid来定位数据行的.rowid也是oracle中内置的一个标量数据类型 rowid有一下特点; 是数据库中每一行 ...

随机推荐

  1. MFC 堆栈溢出 test dword ptr [eax],eax ; probe page.

    今天调试程序的时候,发现一个奇怪的问题,之前调试都没问题的,今早加了一点东西,就出现错误,跳到调试位置,如下4行红色部分 ; Find next lower page and probe cs20: ...

  2. display 与 visibility

    项目开发中经常会遇到需要显示和隐藏DOM元素.常用的两个是display,visibility属性,高级点的会用到angularJS的ng-show,ng-if指令. W3标准对这个两个属性的解释如下 ...

  3. oracle sql语句中使用if逻辑

    l在 SQL 语句中使用IF-THEN-ELSE 逻辑 l l使用两种方法: •CASE 表达式:SQL99的语法,类似Basic,比较繁琐 •DECODE 函数:Oracle自己的语法,类似Java ...

  4. [转]C++强制类型转换

    dynamic_cast:   通常在基类和派生类之间转换时使用,run-time   castconst_cast:   主要针对const和volatile的转换. static_cast:    ...

  5. [转]javascript函数定义表达式和函数声明的区别

    在javascript中,函数有两种定义写法,函数定义表达式和函数声明,其例子分别如下所示: var test = function(x){ return x; } function test(x){ ...

  6. sql查询每门课程成绩最高的学生

    给出数据库(sco)如下图: 查出每门课程成绩最高的学生 select b.id,b.kemu,b.name,b.chengji from (select kemu,max(chengji) maxc ...

  7. display:inline,display:inline-block,display:block 区别

    之前一直迷惑于display:inline/inline-block/block的异同,在度娘谷哥的帮助下,突然有了一点思路. 按照网上的介绍,inline将对象转化为内联元素,block将对象转化为 ...

  8. trident教程

      (一)理论基础更多理论以后再补充,或者参考书籍1.trident是什么?Trident is a high-level abstraction for doing realtime computi ...

  9. 深入mysql慢查询设置的详解

    set long_query_time=1; #设置慢查询时间为1 秒; set global slow_query_log=on; #开启慢查询日志; show global status like ...

  10. php 编译安装选项

    ./configure --prefix=/usr/local/php/ --with-config-file-path=/etc/php5/cli/ --with-config-file-scan- ...