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就会认为是一个不认 ...
随机推荐
- js自动更新时间+星期
<div class="top_bar" id="cao" height="28px"><script> setIn ...
- 基于 React.js + Redux + Bootstrap 的 Ruby China 示例 (转)
一直学 REACT + METEOR 但路由部分有点问题,参考一下:基于 React.js + Redux + Bootstrap 的 Ruby China 示例 http://react-china ...
- waxpatch修改任意类的用法
例如:修改一个UIView(PJView)的子类和一个NSObject(PJModel)类,则需要在patch.lua文件中声明这两个要修改的类 并且建立这些待修改的类的对应的.lua文件 对应的.l ...
- mysql插入速度
请参考 http://www.3lian.com/edu/2013/07-15/80916.html 分表查询 select * from ( select * from user0 un ...
- centos7修改主机名
临时修改: hostname centos7 永久修改: # hostnamectl set-hostname cen07
- VS2012下X64平台嵌入汇编程序
VS2012在win32平台编译的时候可以很好的支持汇编语言的嵌入.建立一个控制台应用程序,选择空项目.项目建立好之后添加一个.cpp文件.在cpp文件中写入如下代码: #include <io ...
- T-SQL 基础学习 03
局部变量 在T-SQL中,局部变量的名称必须以标记@作为前缀 语法 DECLARE @变量名数据类型 局部变量的赋值 方法一 SET @变量名 = 值 方法二 SELECT @变量名 = 值 SET和 ...
- nodejs review-03
39 Serve different file types with our server 处理文件类型 function content_type(filename) { var ext = pat ...
- oracle触发器与数据导入导出的简单使用
exp cjtxx/123456@192.168.80.231/orcl file=d:\cjtxx.dmp owner=cjtxx [tables=tablename] imp cjttest/12 ...
- a pity
机会只眷顾有准备且自信的人,此生谨记. ——Charles Hsu 2014-09-04