C#利用ODP.NET往oracle中高效插入百万数据

因工作的原因,要使用winform来处理大量的数据,但是c#自带的System.data.OracleClient效率不是很高,在网上找了很久,找到了ODP.NET,是oracle为c#提供的。貌似从vs2010开始,微软开始推荐使用ODP.NET。效率的话,在没有索引的情况下,100万数据,不到10秒。

  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

  

  双击 OraProvCfg.exe,会自动配置环境

  

  

  3.在安装的目录下,依次找到以下dll:

  oci.dll      ociw32.dll     Oracle.DataAccess.dll  orannzsbb11.dll  oraocci11.dll  oraociicus11.dll  OraOps11w.dll

  然后将这些dll放到bin\debug目录下(这里是c/s项目,b/s的话貌似放在bin目录下)

 

  4.在项目中,添加引用,就可以使用了,用法跟自带的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 = 0; 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<stringobject> 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 < 1)  
  16.             {  
  17.                 throw new ArgumentException("必须指定批量插入的字段名称""columnRowData");  
  18.             }  
  19.  
  20.             int iResult = 0;  
  21.             string[] dbColumns = columnRowData.Keys.ToArray();  
  22.             StringBuilder sbCmdText = new StringBuilder();  
  23.             if (columnRowData.Count > 0)  
  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 = 600;//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的,还是可以插入数据,没什么问题,貌似可以向下兼容

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值