• ODP方式,大批量数据写入ORACLE数据库


    项目中在同步数据的时候,需要把获得的数据DataTable,写入oracle数据库

    因为System.Data.OracleClient写入方式写入大批量数据特别慢,改用Oracle.DataAccess写入方式(上代码):

    ODP工具类:

    需要引入命名空间:

    using Oracle.DataAccess;
    using Oracle.DataAccess.Client;
    using Oracle.DataAccess.Types;

      1 ODP_Inserter
      2 {
      3         /// <summary>
      4         /// 数据库连接串
      5         /// </summary>
      6         private string strWMSConn = string.Empty;
      7 
      8         public string StrWMSConn
      9         {
     10             get
     11             {
     12                 if (strWMSConn == string.Empty)
     13                 {
     14                     return GetConnectionString();
     15                 }
     16                 else
     17                 {
     18                     return strWMSConn;
     19                 }
     20             }
     21         }
     22 
     23         /// <summary>
     24         /// 构造函数
     25         /// </summary>
     26         public OracleAccessBatcher()
     27         {
     28             //加载数据库连接串
     29             if (strWMSConn == string.Empty)
     30             {
     31                 GetConnectionString();
     32             }
     33         }
     34 
     35         /// <summary>
     36         /// 加载数据库连接串
     37         /// </summary>
     38         private string GetConnectionString()
     39         {
     40             System.Configuration.AppSettingsReader reader = new System.Configuration.AppSettingsReader();
     41             strWMSConn = reader.GetValue("B2BDataBase", typeof(string)).ToString();
     42             return strWMSConn;
     43         }
     44 
     45         /// <summary>
     46         /// 批量插入数据
     47         /// </summary>
     48         /// <param name="tableName">目的表名称</param>
     49         /// <param name="dataTable">数据源(列名与目的表一致)</param>
     50         /// <returns></returns>
     51         public void BatchInsert(string tableName, DataTable dataTable)
     52         {
     53             if (string.IsNullOrEmpty(tableName))
     54             {
     55                 throw new ArgumentNullException("tableName", "必须指定批量插入的表名称");
     56             }
     57 
     58             if (dataTable == null || dataTable.Rows.Count < 1)
     59             {
     60                 throw new ArgumentException("必须指定批量插入的数据源", "dataTable");
     61             }
     62 
     63             using (OracleConnection conn = new OracleConnection(strWMSConn))
     64             {
     65                 try
     66                 {
     67                     conn.Open();
     68 
     69                     using (OracleCommand cmd = conn.CreateCommand())
     70                     {
     71                         // 绑定批处理的行数
     72                         cmd.ArrayBindCount = dataTable.Rows.Count;
     73                         cmd.BindByName = true;
     74                         cmd.CommandType = CommandType.Text;
     75                         cmd.CommandText = GenerateInsertSql(cmd, tableName, dataTable);
     76                         cmd.CommandTimeout = 600; // 10分钟
     77 
     78                         cmd.ExecuteNonQuery();
     79                     }
     80                 }
     81                 catch (Exception exp)
     82                 {
     83                     throw exp;
     84                 }
     85                 finally
     86                 {
     87                     conn.Close();
     88                 }
     89             }
     90 
     91         }
     92 
     93         /// <summary>
     94         /// 批量更新数据
     95         /// </summary>
     96         /// <param name="tableName">目的表名</param>
     97         /// <param name="keyColumns">条件列名数组(值与目的表列名一致)</param>
     98         /// <param name="dataTable">数据源(列名与目的表一致)</param>
     99         /// <returns></returns>
    100         public int BatchUpdate(string tableName, string[] keyColumns, DataTable dataTable)
    101         {
    102             // 检查输入
    103             if (string.IsNullOrEmpty(tableName))
    104             {
    105                 throw new ArgumentNullException("tableName", "必须指定批量更新的表名称");
    106             }
    107 
    108             if (keyColumns == null || keyColumns.Length == 0)
    109             {
    110                 throw new ArgumentException("必须指定批量更新表的条件列数组", "keyColumns");
    111             }
    112 
    113             if (dataTable == null || dataTable.Rows.Count < 1)
    114             {
    115                 throw new ArgumentException("必须指定批量更新的数据源", "dataTable");
    116             }
    117 
    118             // 无需更新
    119             if (keyColumns.Length >= dataTable.Columns.Count)
    120             {
    121                 throw new ArgumentException("目的表不存在需要更新的列名", "keyColumns&dataTable");
    122             }
    123 
    124             // 条件列是否在表列名中
    125             foreach (string colName in keyColumns)
    126             {
    127                 if (!dataTable.Columns.Contains(colName))
    128                 {
    129                     throw new ArgumentException("用于更新条件的列名不在目的表中", "dataTable");
    130                 }
    131             }
    132 
    133             int iResult = 0;
    134             using (OracleConnection conn = new OracleConnection(strWMSConn))
    135             {
    136                 try
    137                 {
    138                     conn.Open();
    139 
    140                     using (OracleCommand cmd = conn.CreateCommand())
    141                     {
    142                         // 绑定批处理的行数
    143                         cmd.ArrayBindCount = dataTable.Rows.Count;
    144                         cmd.BindByName = true;
    145                         cmd.CommandType = CommandType.Text;
    146                         cmd.CommandText = GenerateUpdateSql(cmd, tableName, keyColumns, dataTable);
    147                         cmd.CommandTimeout = 600; // 10分钟
    148 
    149                         iResult = cmd.ExecuteNonQuery();
    150                     }
    151                 }
    152                 catch (Exception exp)
    153                 {
    154                     throw exp;
    155                 }
    156                 finally
    157                 {
    158                     conn.Close();
    159                 }
    160             }
    161 
    162             return iResult;
    163         }
    164 
    165         /// <summary>
    166         /// 批量删除
    167         /// </summary>
    168         /// <param name="tableName">目标表</param>
    169         /// <param name="columnName">列名(与目的表列名一致)</param>
    170         /// <param name="columnValue">列值</param>
    171         public void BatchDelete(string tableName, string columnName, string columnValue)
    172         {
    173             // 检查输入
    174             if (string.IsNullOrEmpty(tableName))
    175             {
    176                 throw new ArgumentNullException("tableName", "必须指定批量更新的表名称");
    177             }
    178 
    179             if (string.IsNullOrEmpty(columnName))
    180             {
    181                 throw new ArgumentNullException("columnValue", "必须指定删除条件的列名");
    182             }
    183 
    184             string strCmdText = string.Format("delete from {0} where {1} = '{2}'", tableName, columnName, columnValue);
    185 
    186             using (OracleConnection conn = new OracleConnection(strWMSConn))
    187             {
    188                 try
    189                 {
    190                     conn.Open();
    191 
    192                     using (OracleCommand cmd = conn.CreateCommand())
    193                     {
    194                         // 绑定批处理的行数
    195                         //cmd.ArrayBindCount = dataTable.Rows.Count;
    196                         cmd.BindByName = true;
    197                         cmd.CommandType = CommandType.Text;
    198                         cmd.CommandText = strCmdText;
    199                         cmd.CommandTimeout = 600; // 10分钟
    200 
    201                         cmd.ExecuteNonQuery();
    202                     }
    203                 }
    204                 catch (Exception exp)
    205                 {
    206                     throw exp;
    207                 }
    208                 finally
    209                 {
    210                     conn.Close();
    211                 }
    212             }
    213         }
    214 
    215         /// <summary>
    216         /// 生成插入数据的sql语句
    217         /// </summary>
    218         /// <param name="command">SQL命令</param>
    219         /// <param name="tableName">目的表名称</param>
    220         /// <param name="table">目的表数据</param>
    221         /// <returns></returns>
    222         private string GenerateInsertSql(OracleCommand command, string tableName, DataTable table)
    223         {
    224             int cols = table.Columns.Count;
    225             int rows = table.Rows.Count;
    226 
    227             StringBuilder names = new StringBuilder();
    228             StringBuilder values = new StringBuilder();
    229 
    230             for (int i = 0; i < cols; i++)
    231             {
    232                 DataColumn column = table.Columns[i];
    233                 OracleParameter param = new OracleParameter(column.ColumnName, this.GetOracleDbType(column.DataType));
    234                 //OracleParameter param = new OracleParameter(column.ColumnName, OracleDbType.Varchar2);
    235 
    236                 string[] data = new string[rows];
    237                 for (int j = 0; j < rows; j++)
    238                 {
    239                     data[j] = table.Rows[j][column.ColumnName].ToString().TrimEnd();
    240                 }
    241 
    242                 param.Direction = ParameterDirection.Input;
    243                 param.Value = data;
    244                 command.Parameters.Add(param);
    245 
    246                 if (names.Length > 0)
    247                 {
    248                     names.Append(",");
    249                     values.Append(",");
    250                 }
    251                 names.AppendFormat("{0}", column.ColumnName);
    252                 values.AppendFormat("{0}{1}", ":", column.ColumnName);
    253             }
    254             return string.Format("INSERT INTO {0}({1}) VALUES ({2})", tableName, names, values);
    255         }
    256 
    257         /// <summary>
    258         /// 生成更新数据的sql语句
    259         /// </summary>
    260         /// <param name="command"></param>
    261         /// <param name="tableName"></param>
    262         /// <param name="keyColumns"></param>
    263         /// <param name="table"></param>
    264         /// <returns></returns>
    265         private string GenerateUpdateSql(OracleCommand command, string tableName, string[] keyColumns, DataTable table)
    266         {
    267             int cols = table.Columns.Count;
    268             int rows = table.Rows.Count;
    269 
    270             StringBuilder sets = new StringBuilder();
    271             StringBuilder wheres = new StringBuilder();
    272 
    273             for (int i = 0; i < cols; i++)
    274             {
    275                 DataColumn column = table.Columns[i];
    276 
    277                 // 是否为条件列
    278                 bool isCond = false;
    279                 foreach (string cod in keyColumns)
    280                 {
    281                     isCond = cod.Equals(column.ColumnName);
    282                     if (isCond)
    283                     {
    284                         break;
    285                     }
    286                 }
    287 
    288 
    289                 string[] data = new string[rows];
    290                 for (int j = 0; j < rows; j++)
    291                 {
    292                     data[j] = table.Rows[j][column.ColumnName].ToString().TrimEnd();
    293                 }
    294 
    295                 // 设定参数
    296                 OracleParameter param;
    297                 OracleDbType dbType = OracleDbType.Varchar2;
    298 
    299                 dbType = this.GetOracleDbType(column.DataType);
    300                 param = new OracleParameter(column.ColumnName, dbType);
    301                 param.Direction = ParameterDirection.Input;
    302                 param.Value = data;
    303                 command.Parameters.Add(param);
    304 
    305                 // 条件列
    306                 if (isCond)
    307                 {
    308                     if (wheres.Length > 0)
    309                     {
    310                         wheres.Append(" and ");
    311                     }
    312 
    313                     wheres.AppendFormat("{0} = :{0}", column.ColumnName);
    314                 }
    315                 else
    316                 {
    317                     if (sets.Length > 0)
    318                     {
    319                         sets.Append(",");
    320                     }
    321                     sets.AppendFormat("{0} = :{0}", column.ColumnName);
    322                 }
    323             }
    324             return string.Format("update {0} set {1} where {2}", tableName, sets, wheres);
    325         }
    326 
    327         /// <summary>
    328         ///  根据数据类型获取OracleDbType
    329         /// </summary>
    330         /// <param name="value"></param>
    331         /// <returns></returns>        
    332         private OracleDbType GetOracleDbType(object value)
    333         {
    334             //OracleDbType dataType = OracleDbType.Object;
    335             OracleDbType dataType = OracleDbType.Varchar2;
    336 
    337             if (value is string)
    338             {
    339                 dataType = OracleDbType.Varchar2;
    340             }
    341             else if (value is DateTime)
    342             {
    343                 dataType = OracleDbType.TimeStamp;
    344             }
    345             else if (value is int || value is short)
    346             {
    347                 dataType = OracleDbType.Int32;
    348             }
    349             else if (value is long)
    350             {
    351                 dataType = OracleDbType.Int64;
    352             }
    353             else if (value is decimal || value is double)
    354             {
    355                 dataType = OracleDbType.Decimal;
    356             }
    357             else if (value is Guid)
    358             {
    359                 dataType = OracleDbType.Varchar2;
    360             }
    361             else if (value is bool || value is Boolean)
    362             {
    363                 dataType = OracleDbType.Byte;
    364             }
    365             else if (value is byte[])
    366             {
    367                 dataType = OracleDbType.Blob;
    368             }
    369             else if (value is char)
    370             {
    371                 dataType = OracleDbType.Char;
    372             }
    373 
    374             return dataType;
    375         }
    376 
    377         /// <summary>
    378         /// 执行SQL
    379         /// </summary>
    380         /// <param name="strSql"></param>
    381         public void ExecuteSql(string strSql)
    382         {
    383             using (OracleConnection conn = new OracleConnection(strWMSConn))
    384             {
    385                 try
    386                 {
    387                     conn.Open();
    388 
    389                     using (OracleCommand cmd = conn.CreateCommand())
    390                     {
    391                         cmd.BindByName = true;
    392                         cmd.CommandType = CommandType.Text;
    393                         cmd.CommandText = strSql;
    394                         cmd.CommandTimeout = 600;
    395 
    396                         cmd.ExecuteNonQuery();
    397                     }
    398                 }
    399                 catch (Exception exp)
    400                 {
    401                     throw exp;
    402                 }
    403                 finally
    404                 {
    405                     conn.Close();
    406                 }
    407             }
    408         }
    409     }
    View Code

    调用:

     ODP_Inserter batchInsert = new ODP_Inserter();

    batchInsert.BatchInsert("table_name", ConvertTable);//table_name为数据库表名称,ConvertTable为要写入的DataTable

    使用的时候,注意DataTable的数据类型

  • 相关阅读:
    xtrabackup详细用法
    CentOS国内YUM源及配置
    CentOS7系统配置国内yum源和epel源
    Zabbix的定期备份
    Zabbix的邮件告警
    石头剪刀布---组合数取模,数论
    组合数取模介绍----Lucas定理介绍
    乘法逆元
    费马小定理
    欧几里德与扩展欧几里德算法----数论
  • 原文地址:https://www.cnblogs.com/FootPrint-gyx/p/5522927.html
Copyright © 2020-2023  润新知