ODP方式,大批量数据写入ORACLE数据库
项目中在同步数据的时候,需要把获得的数据DataTable,写入oracle数据库
因为System.Data.OracleClient写入方式写入大批量数据特别慢,改用Oracle.DataAccess写入方式(上代码):
ODP工具类:
需要引入命名空间:
using Oracle.DataAccess;
using Oracle.DataAccess.Client;
using Oracle.DataAccess.Types;
ODP_Inserter
{
/// <summary>
/// 数据库连接串
/// </summary>
private string strWMSConn = string.Empty; public string StrWMSConn
{
get
{
if (strWMSConn == string.Empty)
{
return GetConnectionString();
}
else
{
return strWMSConn;
}
}
} /// <summary>
/// 构造函数
/// </summary>
public OracleAccessBatcher()
{
//加载数据库连接串
if (strWMSConn == string.Empty)
{
GetConnectionString();
}
} /// <summary>
/// 加载数据库连接串
/// </summary>
private string GetConnectionString()
{
System.Configuration.AppSettingsReader reader = new System.Configuration.AppSettingsReader();
strWMSConn = reader.GetValue("B2BDataBase", typeof(string)).ToString();
return strWMSConn;
} /// <summary>
/// 批量插入数据
/// </summary>
/// <param name="tableName">目的表名称</param>
/// <param name="dataTable">数据源(列名与目的表一致)</param>
/// <returns></returns>
public void BatchInsert(string tableName, DataTable dataTable)
{
if (string.IsNullOrEmpty(tableName))
{
throw new ArgumentNullException("tableName", "必须指定批量插入的表名称");
} if (dataTable == null || dataTable.Rows.Count < )
{
throw new ArgumentException("必须指定批量插入的数据源", "dataTable");
} using (OracleConnection conn = new OracleConnection(strWMSConn))
{
try
{
conn.Open(); using (OracleCommand cmd = conn.CreateCommand())
{
// 绑定批处理的行数
cmd.ArrayBindCount = dataTable.Rows.Count;
cmd.BindByName = true;
cmd.CommandType = CommandType.Text;
cmd.CommandText = GenerateInsertSql(cmd, tableName, dataTable);
cmd.CommandTimeout = ; // 10分钟 cmd.ExecuteNonQuery();
}
}
catch (Exception exp)
{
throw exp;
}
finally
{
conn.Close();
}
} } /// <summary>
/// 批量更新数据
/// </summary>
/// <param name="tableName">目的表名</param>
/// <param name="keyColumns">条件列名数组(值与目的表列名一致)</param>
/// <param name="dataTable">数据源(列名与目的表一致)</param>
/// <returns></returns>
public int BatchUpdate(string tableName, string[] keyColumns, DataTable dataTable)
{
// 检查输入
if (string.IsNullOrEmpty(tableName))
{
throw new ArgumentNullException("tableName", "必须指定批量更新的表名称");
} if (keyColumns == null || keyColumns.Length == )
{
throw new ArgumentException("必须指定批量更新表的条件列数组", "keyColumns");
} if (dataTable == null || dataTable.Rows.Count < )
{
throw new ArgumentException("必须指定批量更新的数据源", "dataTable");
} // 无需更新
if (keyColumns.Length >= dataTable.Columns.Count)
{
throw new ArgumentException("目的表不存在需要更新的列名", "keyColumns&dataTable");
} // 条件列是否在表列名中
foreach (string colName in keyColumns)
{
if (!dataTable.Columns.Contains(colName))
{
throw new ArgumentException("用于更新条件的列名不在目的表中", "dataTable");
}
} int iResult = ;
using (OracleConnection conn = new OracleConnection(strWMSConn))
{
try
{
conn.Open(); using (OracleCommand cmd = conn.CreateCommand())
{
// 绑定批处理的行数
cmd.ArrayBindCount = dataTable.Rows.Count;
cmd.BindByName = true;
cmd.CommandType = CommandType.Text;
cmd.CommandText = GenerateUpdateSql(cmd, tableName, keyColumns, dataTable);
cmd.CommandTimeout = ; // 10分钟 iResult = cmd.ExecuteNonQuery();
}
}
catch (Exception exp)
{
throw exp;
}
finally
{
conn.Close();
}
} return iResult;
} /// <summary>
/// 批量删除
/// </summary>
/// <param name="tableName">目标表</param>
/// <param name="columnName">列名(与目的表列名一致)</param>
/// <param name="columnValue">列值</param>
public void BatchDelete(string tableName, string columnName, string columnValue)
{
// 检查输入
if (string.IsNullOrEmpty(tableName))
{
throw new ArgumentNullException("tableName", "必须指定批量更新的表名称");
} if (string.IsNullOrEmpty(columnName))
{
throw new ArgumentNullException("columnValue", "必须指定删除条件的列名");
} string strCmdText = string.Format("delete from {0} where {1} = '{2}'", tableName, columnName, columnValue); using (OracleConnection conn = new OracleConnection(strWMSConn))
{
try
{
conn.Open(); using (OracleCommand cmd = conn.CreateCommand())
{
// 绑定批处理的行数
//cmd.ArrayBindCount = dataTable.Rows.Count;
cmd.BindByName = true;
cmd.CommandType = CommandType.Text;
cmd.CommandText = strCmdText;
cmd.CommandTimeout = ; // 10分钟 cmd.ExecuteNonQuery();
}
}
catch (Exception exp)
{
throw exp;
}
finally
{
conn.Close();
}
}
} /// <summary>
/// 生成插入数据的sql语句
/// </summary>
/// <param name="command">SQL命令</param>
/// <param name="tableName">目的表名称</param>
/// <param name="table">目的表数据</param>
/// <returns></returns>
private string GenerateInsertSql(OracleCommand command, string tableName, DataTable table)
{
int cols = table.Columns.Count;
int rows = table.Rows.Count; StringBuilder names = new StringBuilder();
StringBuilder values = new StringBuilder(); for (int i = ; i < cols; i++)
{
DataColumn column = table.Columns[i];
OracleParameter param = new OracleParameter(column.ColumnName, this.GetOracleDbType(column.DataType));
//OracleParameter param = new OracleParameter(column.ColumnName, OracleDbType.Varchar2); string[] data = new string[rows];
for (int j = ; j < rows; j++)
{
data[j] = table.Rows[j][column.ColumnName].ToString().TrimEnd();
} param.Direction = ParameterDirection.Input;
param.Value = data;
command.Parameters.Add(param); if (names.Length > )
{
names.Append(",");
values.Append(",");
}
names.AppendFormat("{0}", column.ColumnName);
values.AppendFormat("{0}{1}", ":", column.ColumnName);
}
return string.Format("INSERT INTO {0}({1}) VALUES ({2})", tableName, names, values);
} /// <summary>
/// 生成更新数据的sql语句
/// </summary>
/// <param name="command"></param>
/// <param name="tableName"></param>
/// <param name="keyColumns"></param>
/// <param name="table"></param>
/// <returns></returns>
private string GenerateUpdateSql(OracleCommand command, string tableName, string[] keyColumns, DataTable table)
{
int cols = table.Columns.Count;
int rows = table.Rows.Count; StringBuilder sets = new StringBuilder();
StringBuilder wheres = new StringBuilder(); for (int i = ; i < cols; i++)
{
DataColumn column = table.Columns[i]; // 是否为条件列
bool isCond = false;
foreach (string cod in keyColumns)
{
isCond = cod.Equals(column.ColumnName);
if (isCond)
{
break;
}
} string[] data = new string[rows];
for (int j = ; j < rows; j++)
{
data[j] = table.Rows[j][column.ColumnName].ToString().TrimEnd();
} // 设定参数
OracleParameter param;
OracleDbType dbType = OracleDbType.Varchar2; dbType = this.GetOracleDbType(column.DataType);
param = new OracleParameter(column.ColumnName, dbType);
param.Direction = ParameterDirection.Input;
param.Value = data;
command.Parameters.Add(param); // 条件列
if (isCond)
{
if (wheres.Length > )
{
wheres.Append(" and ");
} wheres.AppendFormat("{0} = :{0}", column.ColumnName);
}
else
{
if (sets.Length > )
{
sets.Append(",");
}
sets.AppendFormat("{0} = :{0}", column.ColumnName);
}
}
return string.Format("update {0} set {1} where {2}", tableName, sets, wheres);
} /// <summary>
/// 根据数据类型获取OracleDbType
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
private OracleDbType GetOracleDbType(object value)
{
//OracleDbType dataType = OracleDbType.Object;
OracleDbType dataType = OracleDbType.Varchar2; if (value is string)
{
dataType = OracleDbType.Varchar2;
}
else if (value is DateTime)
{
dataType = OracleDbType.TimeStamp;
}
else if (value is int || value is short)
{
dataType = OracleDbType.Int32;
}
else if (value is long)
{
dataType = OracleDbType.Int64;
}
else if (value is decimal || value is double)
{
dataType = OracleDbType.Decimal;
}
else if (value is Guid)
{
dataType = OracleDbType.Varchar2;
}
else if (value is bool || value is Boolean)
{
dataType = OracleDbType.Byte;
}
else if (value is byte[])
{
dataType = OracleDbType.Blob;
}
else if (value is char)
{
dataType = OracleDbType.Char;
} return dataType;
} /// <summary>
/// 执行SQL
/// </summary>
/// <param name="strSql"></param>
public void ExecuteSql(string strSql)
{
using (OracleConnection conn = new OracleConnection(strWMSConn))
{
try
{
conn.Open(); using (OracleCommand cmd = conn.CreateCommand())
{
cmd.BindByName = true;
cmd.CommandType = CommandType.Text;
cmd.CommandText = strSql;
cmd.CommandTimeout = ; cmd.ExecuteNonQuery();
}
}
catch (Exception exp)
{
throw exp;
}
finally
{
conn.Close();
}
}
}
}
调用:
ODP_Inserter batchInsert = new ODP_Inserter();
batchInsert.BatchInsert("table_name", ConvertTable);//table_name为数据库表名称,ConvertTable为要写入的DataTable
使用的时候,注意DataTable的数据类型
ODP方式,大批量数据写入ORACLE数据库的更多相关文章
- 极限挑战—C#+ODP 100万条数据导入Oracle数据库仅用不到1秒
链接地址:http://www.cnblogs.com/armyfai/p/4646213.html 要:在这里我们将看到的是C#中利用ODP实现在Oracle数据库中瞬间导入百万级数据,这对快速批量 ...
- 批量Excel数据导入Oracle数据库
由于一直基于Oracle数据库上做开发,因此常常会需要把大量的Excel数据导入到Oracle数据库中,其实如果从事SqlServer数据库的开发,那么思路也是一样的,本文主要介绍如何导入Excel数 ...
- 将pandas的DataFrame数据写入MySQL数据库 + sqlalchemy
将pandas的DataFrame数据写入MySQL数据库 + sqlalchemy import pandas as pd from sqlalchemy import create_engine ...
- 代码执行批量Excel数据导入Oracle数据库
由于基于Oracle数据库上做开发,因此常常会需要把大量的Excel数据导入到Oracle数据库中,其实如果从事SqlServer数据库的开发,那么思路也是一样的,本文主要介绍如何导入Excel数据进 ...
- 在.NetCore(C#)中使用ODP.NET Core+Dapper操作Oracle数据库
前言 虽然一直在说"去IOE化",但是在国企和政府,Oracle的历史包袱实在太重了,甚至很多业务逻辑都是写在Oracle的各种存储过程里面实现的-- 我们的系统主要的技术栈是Dj ...
- PHP如何通过SQL语句将数据写入MySQL数据库呢?
1,php和MySQL建立连接关系 2,打开 3,接受页面数据,PHP录入到指定的表中 1.2两步可直接使用一个数据库链接文件即可:conn.php <?phpmysql_connect(&qu ...
- 利用TOAD实现把EXCEL数据导入oracle数据库
利用TOAD实现把EXCEL数据导入oracle数据库 工具: Toad11.7z(百度搜索,直接下载) 1.将Excel文件中某些字段导入到Oracle数据库的对应表 连接想要导入的数据库 ,然 ...
- 用python在后端将数据写入到数据库并读取
用python在后端将数据写入到数据库: # coding:utf- import pandas as pd from sqlalchemy import create_engine # 初始化数据库 ...
- FIREDAC(DELPHI10 or 10.1)提交数据给ORACLE数据库的一个不是BUG的BUG
发现FIREDAC(DELPHI10 or 10.1)提交数据给ORACLE数据库的一个不是BUG的BUG,提交的表名大小写是敏感的. 只要有一个表名字母的大小写不匹配,ORACLE就会认为是一个不认 ...
随机推荐
- day3
程序1: 实现简单的shell sed替换功能 ]new = sys.argv[]file_name = sys.argv[]tmp_file ="tmpfile"open(tmp ...
- 2014 39th ACM-ICPC 西安赛区 总结
西安,打铁. 出发前听说是大赛区,签到的时候看了秩序册的队伍情况,264支队伍. 在听说是大赛区之前,我觉得我们队应该是银首,运气好+发挥超常的话或许有金,即保银冲金. 听到大赛区之后,觉得可能金区有 ...
- iOS 查询数组中的对象
简述:Cocoa框架中的NSPredicate用于查询,原理和用法都类似于SQL中的where,作用相当于数据库的过滤取. 定义(最常用到的方法): NSPredicate *ca = [NSPred ...
- Android笔记:android的适配
public int Dp2Px(Context context, float dp) { final float scale = context.getResources().getDisplayM ...
- Excel 回归分析
1 分析两个变量和一个因变量的关系 降水,温度与生长的关系曲线 降水是连续的数,温度有三个温室,每个温室一个温度,生长也是连续的数. 作图的方法是将降水放在一列,然后生长根据温度放三列,同一个温度的放 ...
- SQL语句汇总
1.查询出来数据保留小数点2位,并且0.01时候,不会展示为.01. select to_char(0.1,'fm9999999990.00') from dual; 2.wm_concat ...
- Android平台下OpenCV移植与使用---基于C/C++
在<Android Studio增加NDK代码编译支持--Mac环境>和<Mac平台下Opencv开发环境搭建>两篇文章中,介绍了如何使用NDK环境和Opencv环境搭建与测试 ...
- NYOJ题目28大数阶乘
-------------------------------------祭出BigInteger AC代码: import java.math.BigInteger; import java.uti ...
- ASP.NET Core和Angular 2双剑合璧
(此文章同时发表在本人微信公众号"dotNET每日精华文章",欢迎右边二维码来关注.) 题记:两个还没有正式发布的东西一起用,是什么效果? 效果当然会很好了(我猜的),那么如何在A ...
- IOC装配Bean(注解方式)
Spring的注解装配Bean Spring2.5 引入使用注解去定义Bean @Component 描述Spring框架中Bean Spring的框架中提供了与@Component注解等效的三个注解 ...