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就会认为是一个不认 ...
随机推荐
- 【Maven】运行项目
1.run as maven clean 清除原有的编译结果重新编译一次. 2.run as maven bulid.. goals:package tomcat7:deploy 打包到Tomcat7 ...
- xss小试
javascript:alert(document.cookie)javascript:alert(document.domain) 预防: HTTP cookie设置为readOnly 豆瓣 coo ...
- Angular2 模板语法
1. 说明 Angular2的模板用来显示组件外观,作为视图所用,用法和html语法基本一致,最简单的Angular2的模板就是一段html代码.Angular模板语法主要包括以下几个部分: l 直接 ...
- vue学习
2016年12月2日 今天学习Vue.js,对于未知的知识,一脸懵逼.记录学习新知识的路程,为以后学习更多的新知识一个引导.以后学会了之后再回来看看, 回忆一下会与不会的区别在哪.这样以后学习可以更快 ...
- 【JavaScript中的正则表达式】
原文地址:http://blog.csdn.net/xh16319/article/details/9987847 1. 正则表达式规则 1.1 普通字符 字母.数字.汉字.下划线.以及后边章节中没有 ...
- 对DIP IoC DI的理解与运用
DIP,IoC,DI基本概念 依赖倒置原则(DIP,Dependency Inverse Principle):强调系统的“高层组件”不应当依赖于“底层组件”,并且不论是“高层组件”还是“底层组件”都 ...
- Win7+Ubuntu双系统安装完成后时间不一致相差大概8小时
Win7+Ubuntu双系统时间不一致 解决方法: 第一种在Windows下进行如下修改: 在 注册表项:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Con ...
- windows消息钩子注册底层机制浅析
标 题: [原创]消息钩子注册浅析 作 者: RootSuLe 时 间: 2011-06-18,23:10:34 链 接: http://bbs.pediy.com/showthread.php?t= ...
- BestCoder Round #85(ZOJ1569尚未验证)
A题 子序列和啊,就要想到前缀和的差.这个转换一定要!记着!那么i到j的一段子序列和Sij%m == 0就等价于(Sj-Si-1)%m == 0 了,那么什么意思呢?就是如果有两段前缀和%m的模是一 ...
- 10 Cookie/Session
JSP/EL入门 * SUN提供了开发WEB资源的技术 Servlet/JSP * response.getWriter().write(); ...