using System.Data.OracleClient; //using Oracle.DataAccess.Client; using System.Data; using System; using System.Data.Common; using System.Reflection; using CYQ.Data.Tool; using CYQ.Data.Cache; namespace CYQ.Data { internal class OracleDal : DbBase { /// /// 区分Oracle11和Oracle12的Dll名称。 /// public static string ManagedName = "Managed"; public OracleDal(ConnObject co) : base(co) { } protected override void AddReturnPara() { if (!Com.Parameters.Contains("ResultCount")) { AddParameters("ResultCount", DBNull.Value, DbType.Int32, -1, ParameterDirection.Output);//记录总数在最后一位 } if (!Com.Parameters.Contains("ResultCursor")) { AddCustomePara("ResultCursor", ParaType.Cursor, DBNull.Value, null); } } internal override void AddCustomePara(string paraName, ParaType paraType, object value, string typeName) { if (IsUseOdpNet) { AddParaForOdpNet(paraName, paraType, value); } else { AddParaForOracleClient(paraName, paraType, value); } } private void AddParaForOracleClient(string paraName, ParaType paraType, object value) { if (Com.Parameters.Contains(paraName)) { return; } OracleParameter para = new OracleParameter(); para.ParameterName = paraName; switch (paraType) { case ParaType.Cursor: case ParaType.OutPut: if (paraType == ParaType.Cursor) { para.OracleType = OracleType.Cursor; } else { para.OracleType = OracleType.NVarChar; para.Size = 4000; } para.Direction = ParameterDirection.Output; break; case ParaType.ReturnValue: para.OracleType = OracleType.Int32; para.Direction = ParameterDirection.ReturnValue; break; case ParaType.CLOB: case ParaType.NCLOB: para.OracleType = paraType == ParaType.CLOB ? OracleType.Clob : OracleType.NClob; para.Direction = ParameterDirection.Input; if (value != null) { para.Value = value; } break; } Com.Parameters.Add(para); } private void AddParaForOdpNet(string paraName, ParaType paraType, object value) { Assembly ass = GetAssembly(); //工厂方法理解点 DbParameter para = ass.CreateInstance("Oracle." + ManagedName + "DataAccess.Client.OracleParameter") as DbParameter; para.ParameterName = paraName; switch (paraType) { case ParaType.Cursor: case ParaType.OutPut: if (paraType == ParaType.Cursor) { para.GetType().GetProperty("OracleDbType").SetValue(para, OracleDbType.RefCursor, null); } else { para.DbType = DbType.String; para.Size = 4000; } para.Direction = ParameterDirection.Output; value = DBNull.Value; break; case ParaType.ReturnValue: para.DbType = DbType.Int32; para.Direction = ParameterDirection.ReturnValue; value = DBNull.Value; break; case ParaType.CLOB: case ParaType.NCLOB: para.GetType().GetProperty("OracleDbType").SetValue(para, paraType == ParaType.CLOB ? OracleDbType.Clob : OracleDbType.NClob, null); para.Direction = ParameterDirection.Input; if (value != null) { para.Value = value; } break; } Com.Parameters.Add(para); } public override char Pre { get { return ':'; } } internal static Assembly GetAssembly() { object ass = CacheManage.LocalInstance.Get("OracleClient_Assembly"); if (ass == null) { //try //{ ass = Assembly.Load("Oracle." + ManagedName + "DataAccess"); CacheManage.LocalInstance.Set("OracleClient_Assembly", ass, 10080); //} //catch(Exception err) //{ // Error.Throw(errMsg); //} } return ass as Assembly; } /// /// 抽象工厂 /// protected override DbProviderFactory GetFactory(string providerName) { if (IsUseOdpNet) { object factory = CacheManage.LocalInstance.Get("OracleClient_Factory"); if (factory == null) { Assembly ass = GetAssembly(); factory = ass.CreateInstance("Oracle." + ManagedName + "DataAccess.Client.OracleClientFactory"); if (factory == null) { throw new System.Exception("Can't Create OracleClientFactory in Oracle." + ManagedName + "DataAccess.dll"); } else { CacheManage.LocalInstance.Set("OracleClient_Factory", factory, 10080); } } return factory as DbProviderFactory; } else { return base.GetFactory(providerName); } } /// /// 值-1未初始化;0使用OracleClient;1使用DataAccess;2使用ManagedDataAccess /// internal static int clientType = -1; private static readonly object lockObj = new object(); /// /// 是否使用Oracle的ODP.NET组件。 /// private bool IsUseOdpNet { get { if (clientType == -1) { lock (lockObj) { if (clientType == -1) { if (AppConfig.GetConn(base.conn).IndexOf("host", StringComparison.OrdinalIgnoreCase) == -1) { clientType = 0; } else { string path = AppConst.RunFolderPath; if (System.IO.File.Exists(path + "Oracle." + ManagedName + "DataAccess.dll"))//Oracle 12 { clientType = 2; } else if (System.IO.File.Exists(path + "Oracle.DataAccess.dll")) ////Oracle 11 { ManagedName = ""; clientType = 1; } else { clientType = 0; Log.WriteLog("Can't find Oracle.ManagedDataAccess.dll or Oracle.DataAccess.dll on the path:" + path); } } } } } return clientType > 0; } } protected override bool IsExistsDbName(string dbName) { return DBTool.TestConn(GetNewConn(dbName)); } } internal enum OracleDbType { //BFile = 101, //Blob = 102, //Byte = 103, //Char = 104, Clob = 105, //Date = 106, //Decimal = 107, //Double = 108, //Long = 109, //LongRaw = 110, //Int16 = 111, //Int32 = 112, //Int64 = 113, //IntervalDS = 114, //IntervalYM = 115, NClob = 116, //NChar = 117, //NVarchar2 = 119, //Raw = 120, RefCursor = 121, //Single = 122, //TimeStamp = 123, //TimeStampLTZ = 124, //TimeStampTZ = 125, //Varchar2 = 126, //XmlType = 127, //Array = 128, //Object = 129, //Ref = 130, //BinaryDouble = 132, //BinaryFloat = 133, } }