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     }

调用:

ODP_Inserter batchInsert = new ODP_Inserter();

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

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

时间: 2024-08-02 21:29:31

ODP方式,大批量数据写入ORACLE数据库的相关文章

极限挑战—C#+ODP 100万条数据导入Oracle数据库仅用不到1秒

链接地址:http://www.cnblogs.com/armyfai/p/4646213.html 要:在这里我们将看到的是C#中利用ODP实现在Oracle数据库中瞬间导入百万级数据,这对快速批量导入的实现有重要意义. .Net程序中可以通过ODP调用特性,对Oracle数据库进行操作,今天来讲一下数据批量插入的功能,所用技术不高不深,相信很多朋友都接触过,小弟班门弄斧了,呵呵.这篇文章是上篇文章的续集,因为上一次试验的征集结果没有突破4秒的方法,所以这次继续挑战与挖掘新方法,虽然是Orac

代码执行批量Excel数据导入Oracle数据库

由于基于Oracle数据库上做开发,因此常常会需要把大量的Excel数据导入到Oracle数据库中,其实如果从事SqlServer数据库的开发,那么思路也是一样的,本文主要介绍如何导入Excel数据进入Oracle数据库的内容. 方法一: 1.准备数据:在excel中构造出需要的数据 2.将excel中的数据另存为文本文件(有制表符分隔的) 3.将新保存到文本文件中的数据导入到pl*sql中 在pl*sql中选择tools--text importer,在出现的窗口中选择Data from Te

读取csv文件,写入oracle数据库

/* * @(#)DataParse.java 2014年4月28日 */ package com.yihaodian.sa.doData; import java.io.BufferedReader;import java.io.File;import java.io.FileNotFoundException;import java.io.FileReader;import java.io.IOException;import java.sql.Connection;import java.

将pandas的DataFrame数据写入MySQL数据库 + sqlalchemy

将pandas的DataFrame数据写入MySQL数据库 + sqlalchemy [python] view plain copy print? import pandas as pd from sqlalchemy import create_engine ##将数据写入mysql的数据库,但需要先通过sqlalchemy.create_engine建立连接,且字符编码设置为utf8,否则有些latin字符不能处理 yconnect = create_engine('mysql+mysql

利用TOAD实现把EXCEL数据导入oracle数据库

利用TOAD实现把EXCEL数据导入oracle数据库 工具:   Toad11.7z(百度搜索,直接下载) 1.将Excel文件中某些字段导入到Oracle数据库的对应表 连接想要导入的数据库 ,然后Database->Import->Table Data打开了导入窗口,如下图   选择一个数据库表,点击Show Data按钮,可以显示表中的内容 其中schema 就是这张表的所属用户 Object type 就是 table Object name 就是表的名称 Commit mode 

PHP如何通过SQL语句将数据写入MySQL数据库呢?

1,php和MySQL建立连接关系 2,打开 3,接受页面数据,PHP录入到指定的表中 1.2两步可直接使用一个数据库链接文件即可:conn.php <?phpmysql_connect("localhost","root","");//连接MySQLmysql_select_db("hello");//选择数据库?> 当然,前提是已经安装WEB服务器.PHP和MySQL,并且建立MySQL表“webjx” mys

用python在后端将数据写入到数据库并读取

用python在后端将数据写入到数据库: # coding:utf-8 import pandas as pd from sqlalchemy import create_engine # 初始化数据库连接,使用pymysql模块 # MySQL的用户:root, 密码:147369, 端口:3306,数据库:mydb engine = create_engine('mysql+pymysql://root:[email protected]:3306/python1') import nump

Java基础103 Hibernate技术连接MySQL数据和Oracle数据库的配置方法

1.Hibernate技术连接MySQL数据 User.hbm.xml 配置文件 <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernat

C#获取并写入ORACLE数据库中中英文字符集问题

背景: 开发语言:C# 开发工具:VS2010 A方ORACLE数据库:中文字符集 B方ORACLE数据库:英文字符集 传递方式:webservice方式(取数据,并把取出的数据放到DataTable中,循环回写入B方的存储过程中) 问题: 从A方库里获取数据插入到B方库里写的存储过程里,到B方数据库后,汉字都变为乱码(问号较多) 解决方法: 方法一:最初从A方库取数据时用ORACLE的转换函数UTL_RAW.CAST_TO_RAW转换下该字段,即select UTL_RAW.CAST_TO_R