using Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using NHibernate;
using Oracle.DataAccess.Client;
using System.IO;
using System.Diagnostics;
namespace Holworth.Utility.BulkCopy
{
public class OracleBulkCopy : BulkCopyTemplate, IBulkCopy
{
private static object lockBulkCopy = new object();
private static IBulkCopy instance;
public static IBulkCopy Instance
{
get
{
if (instance == null)
{
lock (lockBulkCopy)
{
instance = new OracleBulkCopy();
}
}
return instance;
}
}
private Spring.Context.IApplicationContext _ctx;
public Spring.Context.IApplicationContext ctx
{
get
{
if (_ctx == null)
{
_ctx = Spring.Context.Support.ContextRegistry.GetContext();
}
return _ctx;
}
}
private Framework.IService.ICommonService _dao;
public Framework.IService.ICommonService Dao
{
get
{
if (_dao == null)
{
_dao = (Framework.IService.ICommonService)ctx["CommonService"];
}
return _dao;
}
set
{
_dao = value;
}
}
private static object lockSequence = new object();
public override long GetSequenceCurrentVal(string v_seq)
{
long inCreId = 1;
try
{
QueryInfo searchInfo = new QueryInfo();
searchInfo.CustomSQL = $"select {v_seq}.NEXTVAL from dual";
var table = Dao.ExecuteDataSet(searchInfo).Tables[0];
inCreId = Convert.ToInt64(table.Rows[0][0].ToString());
}
catch (Exception ex)
{
try
{
var info = new QueryInfo();
info.CustomSQL = $"create sequence {v_seq} minvalue 1 maxvalue 999999999999999 start with 1 increment by 1 cache 20";
Dao.ExecuteNonQuery(info);
var searchInfo = new QueryInfo();
searchInfo.CustomSQL = $"select {v_seq}.NEXTVAL from dual";
var table = Dao.ExecuteDataSet(searchInfo).Tables[0];
inCreId = Convert.ToInt64(table.Rows[0][0].ToString());
}
catch (Exception e)
{
Logger.Fatal(e);
throw e;
}
}
return inCreId;
}
public override void ChangeSequenceStep(string v_seq, int rowCount)
{
var info = new QueryInfo();
info.NamedQuery = "PRO_SEQUENCE";
info.Parameters.Add("v_simulation_number", rowCount);
info.Parameters.Add("v_seq", v_seq);
Dao.ExecuteNonQuery(info);
}
public override void SequenceStepReset(string v_seq)
{
var info = new QueryInfo();
info.NamedQuery = "PRO_SEQUENCE";
info.Parameters.Add("v_simulation_number", -1);
info.Parameters.Add("v_seq", v_seq);
Dao.ExecuteNonQuery(info);
}
public override void BulkCopyImport(object bulkcopy, string targetTable, string IdField, DataTable dt, BulkCopyParam bp = default(BulkCopyParam))
{
try
{
if (dt.Rows.Count > 0)
{
var session = Dao.GetCurrentSession();
object cname = "";
var sql = "";
#region oracle 查看主键约束的名称
sql = $@"select a.constraint_name c,a.column_name
from user_cons_columns a,user_constraints b
where a.constraint_name=b.constraint_name
and b.constraint_type='P'
and b.owner='{Holworth.Utility.HraUtility.GetDataBaseInfo(AppEnum.Web).user}'
and a.table_name='{targetTable.ToUpper()}'";
#endregion
try
{
cname = session.CreateSQLQuery(sql).AddScalar("c", NHibernateUtil.String).UniqueResult();
if (cname != null)
{
sql = $@"alter table {targetTable} drop constraint {cname}";
}
if (bp != null && bp.Generator != GenerateValue.UUID)
session.CreateSQLQuery(sql).ExecuteUpdate();
}
catch (Exception ex)
{
HttpMessages.Instance().PushMessage(ex.Message + "详细" + ex.StackTrace);
Logger.Fatal(ex);
}
BulkCopyImport2(targetTable, IdField, dt, bp);
try
{
if (cname != null)
{
sql = $@"alter table {targetTable} add constraint {cname} primary key({IdField})";
}
else
{
int len = targetTable.Length > 27 ? 27 : targetTable.Length;
sql = $@"alter table {targetTable} add constraint pk_{targetTable.Substring(0, len)} primary key({IdField})";
}
if (bp != null && bp.Generator != GenerateValue.UUID)
session.CreateSQLQuery(sql).ExecuteUpdate();
}
catch (Exception ex)
{
Logger.Fatal(ex);
}
}
}
catch (Exception ex)
{
Logger.Fatal(ex);
HttpMessages.Instance().PushMessage("BULKCOPY表:" + targetTable + "异常因为:" + ex.Message + "堆栈信息:" + ex.StackTrace);
throw ex;
}
}
//public override void BulkCopyImport(object bulkcopy, string targetTable, string IdField, DataTable dt, BulkCopyParam bp = default(BulkCopyParam))
//{
// try
// {
// Oracle.DataAccess.Client.OracleBulkCopy copy = bulkcopy as Oracle.DataAccess.Client.OracleBulkCopy;
// if (dt != null && dt.Rows.Count > 0)
// {
// copy.DestinationTableName = targetTable;
// copy.BulkCopyTimeout = 500;
// copy.BatchSize = 1000;
// }
// if (dt.Rows.Count > 0)
// {
// var session = Dao.GetCurrentSession();
// object cname = "";
// var sql = "";
// #region oracle 查看主键约束的名称
// sql = $@"select a.constraint_name c,a.column_name
// from user_cons_columns a,user_constraints b
// where a.constraint_name=b.constraint_name
// and b.constraint_type='P'
// and b.owner='{Holworth.Utility.HraUtility.GetDataBaseInfo(AppEnum.Web).user}'
// and a.table_name='{targetTable.ToUpper()}'";
// #endregion
// try
// {
// cname = session.CreateSQLQuery(sql).AddScalar("c", NHibernateUtil.String).UniqueResult();
// if (cname != null)
// {
// sql = $@"alter table {targetTable} drop constraint {cname}";
// }
// if (bp != null && bp.Generator != GenerateValue.UUID)
// session.CreateSQLQuery(sql).ExecuteUpdate();
// }
// catch (Exception ex)
// {
// HttpMessages.Instance().PushMessage(ex.Message + "详细" + ex.StackTrace);
// Logger.Fatal(ex);
// }
// copy.WriteToServer(dt);
// try
// {
// if (cname != null)
// {
// sql = $@"alter table {targetTable} add constraint {cname} primary key({IdField})";
// }
// else
// {
// int len = targetTable.Length > 27 ? 27 : targetTable.Length;
// sql = $@"alter table {targetTable} add constraint pk_{targetTable.Substring(0, len)} primary key({IdField})";
// }
// if (bp != null && bp.Generator != GenerateValue.UUID)
// session.CreateSQLQuery(sql).ExecuteUpdate();
// }
// catch (Exception ex)
// {
// Logger.Fatal(ex);
// }
// }
// }
// catch (Exception ex)
// {
// Logger.Fatal(ex);
// HttpMessages.Instance().PushMessage("BULKCOPY表:" + targetTable + "异常因为:" + ex.Message + "堆栈信息:" + ex.StackTrace);
// throw ex;
// }
//}
public void BulkCopyImport2(string targetTable, string IdField, DataTable dt, BulkCopyParam bp = default(BulkCopyParam))
{
var adotemplate = Holworth.Utility.HraUtility.GetAdoTemplate();
//设置一个数据库的连接串
int recc = dt.Rows.Count;
string connectStr = adotemplate.DbProvider.ConnectionString;
//"User ID=RAMS_XY_TO_GARY;Password=RAMS_XY_TO_GARY;Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.100.100)(PORT=1521)))(CONNECT_DATA=(SERVER=DEDICATED)(SID=HRA)))";
using (OracleConnection conn = new OracleConnection(connectStr))
{
try
{
OracleCommand command = new OracleCommand();
command.Connection = conn;
//到此为止,还都是我们熟悉的代码,下面就要开始喽
//这个参数需要指定每次批插入的记录数
command.ArrayBindCount = recc;
command.BindByName = true;
command.CommandType = CommandType.Text;
command.CommandTimeout = 600;
//在这个命令行中,用到了参数,参数我们很熟悉,但是这个参数在传值的时候
//用到的是数组,而不是单个的值,这就是它独特的地方
string columns = "";
OracleDbType type = 0;
Dictionary<string, OracleDbType> CsharpTypeMappingOracleDbTypeDict = new Dictionary<string, OracleDbType>();
var columnsInfo = Holworth.Utility.ETLColumnInfoDaoController.Current.GetAllTableColumnsInfo().Where(x => string.Compare(targetTable, x.TableName, true) == 0).ToList();
Dictionary<string, List<object>> valueDict = new Dictionary<string, List<object>>();
var paramDict = new Dictionary<string, OracleParameter>();
foreach (ETLColumnTypeInfo ect in columnsInfo)
{
OracleDbType oracleType = OracleDbType.Varchar2;
if (string.Compare(ect.SqlType, "number", true) == 0)
{
if (ect.Scale > 0)
{
oracleType = OracleDbType.Decimal;
}
else
{
oracleType = OracleDbType.Int32;
}
}
else if (string.Compare(ect.SqlType, OracleDbType.Blob.ToString(), true) == 0)
{
oracleType = OracleDbType.Blob;
}
else if (string.Compare(ect.SqlType, OracleDbType.Byte.ToString(), true) == 0)
{
oracleType = OracleDbType.Byte;
}
else if (string.Compare(ect.SqlType, OracleDbType.Char.ToString(), true) == 0)
{
oracleType = OracleDbType.Char;
}
else if (string.Compare(ect.SqlType, OracleDbType.Clob.ToString(), true) == 0)
{
oracleType = OracleDbType.Clob;
}
else if (string.Compare(ect.SqlType, OracleDbType.Date.ToString(), true) == 0)
{
oracleType = OracleDbType.Date;
}
else if (string.Compare(ect.SqlType, OracleDbType.Decimal.ToString(), true) == 0)
{
oracleType = OracleDbType.Decimal;
}
else if (string.Compare(ect.SqlType, OracleDbType.Double.ToString(), true) == 0)
{
oracleType = OracleDbType.Double;
}
else if (string.Compare(ect.SqlType, OracleDbType.Long.ToString(), true) == 0)
{
oracleType = OracleDbType.Long;
}
else if (string.Compare(ect.SqlType, OracleDbType.LongRaw.ToString(), true) == 0)
{
oracleType = OracleDbType.LongRaw;
}
else if (string.Compare(ect.SqlType, OracleDbType.Int16.ToString(), true) == 0)
{
oracleType = OracleDbType.Int16;
}
else if (string.Compare(ect.SqlType, OracleDbType.Int32.ToString(), true) == 0)
{
oracleType = OracleDbType.Int32;
}
else if (string.Compare(ect.SqlType, OracleDbType.Int64.ToString(), true) == 0)
{
oracleType = OracleDbType.Int64;
}
else if (string.Compare(ect.SqlType, OracleDbType.IntervalDS.ToString(), true) == 0)
{
oracleType = OracleDbType.IntervalDS;
}
else if (string.Compare(ect.SqlType, OracleDbType.IntervalYM.ToString(), true) == 0)
{
oracleType = OracleDbType.IntervalYM;
}
else if (string.Compare(ect.SqlType, OracleDbType.NClob.ToString(), true) == 0)
{
oracleType = OracleDbType.NClob;
}
else if (string.Compare(ect.SqlType, OracleDbType.NChar.ToString(), true) == 0)
{
oracleType = OracleDbType.NChar;
}
else if (string.Compare(ect.SqlType, OracleDbType.NVarchar2.ToString(), true) == 0)
{
oracleType = OracleDbType.NVarchar2;
}
else if (string.Compare(ect.SqlType, OracleDbType.Raw.ToString(), true) == 0)
{
oracleType = OracleDbType.Raw;
}
else if (string.Compare(ect.SqlType, OracleDbType.RefCursor.ToString(), true) == 0)
{
oracleType = OracleDbType.RefCursor;
}
else if (string.Compare(ect.SqlType, OracleDbType.Single.ToString(), true) == 0)
{
oracleType = OracleDbType.Single;
}
else if (string.Compare(ect.SqlType, OracleDbType.TimeStamp.ToString(), true) == 0)
{
oracleType = OracleDbType.TimeStamp;
}
else if (string.Compare(ect.SqlType, OracleDbType.TimeStampLTZ.ToString(), true) == 0)
{
oracleType = OracleDbType.TimeStampLTZ;
}
else if (string.Compare(ect.SqlType, OracleDbType.TimeStampTZ.ToString(), true) == 0)
{
oracleType = OracleDbType.TimeStampTZ;
}
else if (string.Compare(ect.SqlType, OracleDbType.Varchar2.ToString(), true) == 0)
{
oracleType = OracleDbType.Varchar2;
}
else if (string.Compare(ect.SqlType, OracleDbType.XmlType.ToString(), true) == 0)
{
oracleType = OracleDbType.XmlType;
}
else if (string.Compare(ect.SqlType, OracleDbType.Array.ToString(), true) == 0)
{
oracleType = OracleDbType.Array;
}
else if (string.Compare(ect.SqlType, OracleDbType.Object.ToString(), true) == 0)
{
oracleType = OracleDbType.Object;
}
else if (string.Compare(ect.SqlType, OracleDbType.Ref.ToString(), true) == 0)
{
oracleType = OracleDbType.Ref;
}
else if (string.Compare(ect.SqlType, OracleDbType.BinaryDouble.ToString(), true) == 0)
{
oracleType = OracleDbType.BinaryDouble;
}
else if (string.Compare(ect.SqlType, OracleDbType.BinaryFloat.ToString(), true) == 0)
{
oracleType = OracleDbType.BinaryFloat;
}
else
{
}
OracleParameter param = new OracleParameter(ect.ColumnName, oracleType);
param.Direction = ParameterDirection.Input;
command.Parameters.Add(param);
paramDict[ect.ColumnName] = param;
valueDict[ect.ColumnName] = new List<object>();
}
foreach (DataRow dr in dt.Rows)
{
foreach (DataColumn col in dt.Columns)
{
string columnName = col.ColumnName;
if (col.DataType.Name == "DateTime"&&dr[columnName].ToString().StartsWith("0"))
{
dr[columnName] = new DateTime(1900, 1, 1);
}
valueDict[columnName].Add(dr[columnName]);
}
}
foreach (DataColumn col in dt.Columns)
{
string columnName = col.ColumnName;
columns += ":" + columnName + ",";
paramDict[columnName].Value = valueDict[columnName].ToArray();
}
columns = columns.TrimEnd(',');
command.CommandText = $"insert into {targetTable} values({columns})";
conn.Open();
command.ExecuteNonQuery();
}
catch (Exception ex)
{
throw;
}
finally
{
conn.Dispose();
}
}
}
public override void BulkCopyMappingsAdd(object copy, string source, string des)
{
var bulkcopy = copy as Oracle.DataAccess.Client.OracleBulkCopy;
bulkcopy.ColumnMappings.Add(source, des);
}
public override object BuldCopy(object cn)
{
object copy = new Oracle.DataAccess.Client.OracleBulkCopy(cn as Oracle.DataAccess.Client.OracleConnection);
return copy;
}
}
}