zoukankan      html  css  js  c++  java
  • C#利用ODP.NET往oracle中高效插入百万数据

    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:app12product11.2.0client_1odp.netin2.x

      

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

      

      

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

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

      然后将这些dll放到bindebug目录下(这里是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<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 < 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的,还是可以插入数据,没什么问题,貌似可以向下兼容

     
     
     
    标签: oraclec#odp.net百万数据
  • 相关阅读:
    【郑轻邀请赛 G】密室逃脱
    【郑轻邀请赛 C】DOBRI
    【郑轻邀请赛 F】 Tmk吃汤饭
    【郑轻邀请赛 I】这里是天堂!
    【郑轻邀请赛 B】base64解密
    【郑轻邀请赛 A】tmk射气球
    【郑轻邀请赛 H】 维克兹的进制转换
    解决adb command not found以及sdk环境配置
    adb shell 命令详解,android, adb logcat
    Unexpected exception 'Cannot run program ... error=2, No such file or directory' ... adb'
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3303917.html
Copyright © 2011-2022 走看看