diff --git a/Src/Asp.NetCore2/SqlSugar.OceanBaseForOracle/DataTableExtensions/OceanBaseForOracleDataAdapter.cs b/Src/Asp.NetCore2/SqlSugar.OceanBaseForOracle/DataTableExtensions/OceanBaseForOracleDataAdapter.cs
new file mode 100644
index 000000000..e3898c104
--- /dev/null
+++ b/Src/Asp.NetCore2/SqlSugar.OceanBaseForOracle/DataTableExtensions/OceanBaseForOracleDataAdapter.cs
@@ -0,0 +1,157 @@
+using System;
+using System.Collections.Generic;
+using System.Data;
+using System.Data.Odbc;
+using System.Text;
+namespace SqlSugar.OceanBaseForOracle
+{
+ ///
+ /// 数据填充器
+ ///
+ public class OceanBaseForOracleDataAdapter : IDataAdapter
+ {
+ private OdbcCommand command;
+ private string sql;
+ private OdbcConnection _sqlConnection;
+
+ ///
+ /// SqlDataAdapter
+ ///
+ ///
+ public OceanBaseForOracleDataAdapter(OdbcCommand command)
+ {
+ this.command = command;
+ }
+
+ public OceanBaseForOracleDataAdapter()
+ {
+
+ }
+
+ ///
+ /// SqlDataAdapter
+ ///
+ ///
+ ///
+ public OceanBaseForOracleDataAdapter(string sql, OdbcConnection _sqlConnection)
+ {
+ this.sql = sql;
+ this._sqlConnection = _sqlConnection;
+ }
+
+ ///
+ /// SelectCommand
+ ///
+ public OdbcCommand SelectCommand
+ {
+ get
+ {
+ if (this.command == null)
+ {
+ var conn = (OdbcConnection)this._sqlConnection;
+ this.command = conn.CreateCommand();
+ this.command.CommandText = sql;
+ }
+ return this.command;
+ }
+ set
+ {
+ this.command = value;
+ }
+ }
+
+ ///
+ /// Fill
+ ///
+ ///
+ public void Fill(DataTable dt)
+ {
+ if (dt == null)
+ {
+ dt = new DataTable();
+ }
+ var columns = dt.Columns;
+ var rows = dt.Rows;
+ using (var dr = command.ExecuteReader())
+ {
+ for (int i = 0; i < dr.FieldCount; i++)
+ {
+ string name = dr.GetName(i).Trim();
+ if (!columns.Contains(name))
+ columns.Add(new DataColumn(name, dr.GetFieldType(i)));
+ else
+ {
+ columns.Add(new DataColumn(name + i, dr.GetFieldType(i)));
+ }
+ }
+
+ while (dr.Read())
+ {
+ DataRow daRow = dt.NewRow();
+ for (int i = 0; i < columns.Count; i++)
+ {
+ daRow[columns[i].ColumnName] = dr.GetValue(i);
+ }
+ dt.Rows.Add(daRow);
+ }
+ }
+ dt.AcceptChanges();
+ }
+
+ ///
+ /// Fill
+ ///
+ ///
+ public void Fill(DataSet ds)
+ {
+ if (ds == null)
+ {
+ ds = new DataSet();
+ }
+ using (var dr = command.ExecuteReader())
+ {
+ do
+ {
+ var dt = new DataTable();
+ var columns = dt.Columns;
+ var rows = dt.Rows;
+ for (int i = 0; i < dr.FieldCount; i++)
+ {
+ string name = dr.GetName(i).Trim();
+ if (dr.GetFieldType(i).Name == "DateTime")
+ {
+ if (!columns.Contains(name))
+ columns.Add(new DataColumn(name, UtilConstants.DateType));
+ else
+ {
+ columns.Add(new DataColumn(name + i, UtilConstants.DateType));
+ }
+ }
+ else
+ {
+ if (!columns.Contains(name))
+ columns.Add(new DataColumn(name, dr.GetFieldType(i)));
+ else
+ {
+ columns.Add(new DataColumn(name + i, dr.GetFieldType(i)));
+ }
+ }
+ }
+
+ while (dr.Read())
+ {
+ DataRow daRow = dt.NewRow();
+ for (int i = 0; i < columns.Count; i++)
+ {
+ daRow[columns[i].ColumnName] = dr.GetValue(i);
+ }
+ dt.Rows.Add(daRow);
+ }
+ dt.AcceptChanges();
+ ds.Tables.Add(dt);
+ } while (dr.NextResult());
+ }
+ }
+ }
+
+}
diff --git a/Src/Asp.NetCore2/SqlSugar.OceanBaseForOracle/NuGet.exe b/Src/Asp.NetCore2/SqlSugar.OceanBaseForOracle/NuGet.exe
new file mode 100644
index 000000000..6bb79fe53
Binary files /dev/null and b/Src/Asp.NetCore2/SqlSugar.OceanBaseForOracle/NuGet.exe differ
diff --git a/Src/Asp.NetCore2/SqlSugar.OceanBaseForOracle/OceanBase/CodeFirst/OceanBaseForOracleCodeFirst.cs b/Src/Asp.NetCore2/SqlSugar.OceanBaseForOracle/OceanBase/CodeFirst/OceanBaseForOracleCodeFirst.cs
new file mode 100644
index 000000000..2c5703b80
--- /dev/null
+++ b/Src/Asp.NetCore2/SqlSugar.OceanBaseForOracle/OceanBase/CodeFirst/OceanBaseForOracleCodeFirst.cs
@@ -0,0 +1,51 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SqlSugar.OceanBaseForOracle
+{
+ public class OceanBaseForOracleCodeFirst : CodeFirstProvider
+ {
+ public OceanBaseForOracleCodeFirst()
+ {
+ if (DefultLength == 0)
+ DefultLength = 40;
+ }
+ protected override int DefultLength { get; set; }
+
+ protected override void GetDbType(EntityColumnInfo item, Type propertyType, DbColumnInfo result)
+ {
+ if (!string.IsNullOrEmpty(item.DataType))
+ {
+ result.DataType = item.DataType;
+ }
+ else if (propertyType.IsEnum())
+ {
+ result.DataType = this.Context.Ado.DbBind.GetDbTypeName(item.Length > 9 ? UtilConstants.LongType.Name : UtilConstants.IntType.Name);
+ }
+ else
+ {
+ if (propertyType.Name.Equals("Guid", StringComparison.CurrentCultureIgnoreCase))
+ {
+ result.DataType = this.Context.Ado.DbBind.GetDbTypeName(UtilConstants.StringType.Name);
+ if (result.Length <= 1)
+ {
+ result.Length = 36;
+ }
+ }
+ else
+ {
+ result.DataType = this.Context.Ado.DbBind.GetDbTypeName(propertyType.Name);
+ }
+ }
+ }
+
+ protected override void KeyAction(EntityColumnInfo item, DbColumnInfo dbColumn, out bool pkDiff, out bool idEntityDiff)
+ {
+ pkDiff = item.IsPrimarykey != dbColumn.IsPrimarykey;
+ idEntityDiff = false;
+ }
+ }
+}
diff --git a/Src/Asp.NetCore2/SqlSugar.OceanBaseForOracle/OceanBase/DbBind/OceanBaseForOracleDbBind.cs b/Src/Asp.NetCore2/SqlSugar.OceanBaseForOracle/OceanBase/DbBind/OceanBaseForOracleDbBind.cs
new file mode 100644
index 000000000..3c2c914b3
--- /dev/null
+++ b/Src/Asp.NetCore2/SqlSugar.OceanBaseForOracle/OceanBase/DbBind/OceanBaseForOracleDbBind.cs
@@ -0,0 +1,139 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SqlSugar.OceanBaseForOracle
+{
+ public class OceanBaseForOracleDbBind : DbBindProvider
+ {
+ public override string GetDbTypeName(string csharpTypeName)
+ {
+ if (csharpTypeName == UtilConstants.ByteArrayType.Name)
+ return "blob";
+ if (csharpTypeName.ToLower() == "int32")
+ csharpTypeName = "int";
+ if (csharpTypeName.ToLower() == "int16")
+ csharpTypeName = "short";
+ if (csharpTypeName.ToLower() == "int64")
+ csharpTypeName = "long";
+ if (csharpTypeName.ToLower().IsIn("boolean", "bool"))
+ csharpTypeName = "bool";
+ if (csharpTypeName == "Guid")
+ csharpTypeName = "string";
+ if (csharpTypeName == "DateTimeOffset")
+ csharpTypeName = "DateTime";
+ var mappings = this.MappingTypes.Where(it => it.Value.ToString().Equals(csharpTypeName, StringComparison.CurrentCultureIgnoreCase));
+ return mappings.HasValue() ? mappings.First().Key : "varchar";
+ }
+ public override string GetPropertyTypeName(string dbTypeName)
+ {
+ dbTypeName = dbTypeName.ToLower();
+ var propertyTypes = MappingTypes.Where(it => it.Value.ToString().ToLower() == dbTypeName || it.Key.ToLower() == dbTypeName);
+ if (dbTypeName == "int32")
+ {
+ return "int";
+ }
+ else if (dbTypeName == "int64")
+ {
+ return "long";
+ }
+ else if (dbTypeName == "int16")
+ {
+ return "short";
+ }
+ else if (propertyTypes == null)
+ {
+ return "other";
+ }
+ else if (dbTypeName == "xml" || dbTypeName == "string")
+ {
+ return "string";
+ }
+ if (dbTypeName == "byte[]")
+ {
+ return "byte[]";
+ }
+ else if (propertyTypes == null || propertyTypes.Count() == 0)
+ {
+ Check.ThrowNotSupportedException(string.Format(" \"{0}\" Type NotSupported, DbBindProvider.GetPropertyTypeName error.", dbTypeName));
+ return null;
+ }
+ else if (propertyTypes.First().Value == CSharpDataType.byteArray)
+ {
+ return "byte[]";
+ }
+ else
+ {
+ return propertyTypes.First().Value.ToString();
+ }
+ }
+ public override List> MappingTypes
+ {
+ get
+ {
+ var extService = this.Context.CurrentConnectionConfig.ConfigureExternalServices;
+ if (extService != null && extService.AppendDataReaderTypeMappings.HasValue())
+ {
+ return extService.AppendDataReaderTypeMappings.Union(MappingTypesConst).ToList();
+ }
+ else
+ {
+ return MappingTypesConst;
+ }
+ }
+ }
+ public static List> MappingTypesConst = new List>()
+ {
+ new KeyValuePair("int",CSharpDataType.@int),
+ new KeyValuePair("integer",CSharpDataType.@int),
+ new KeyValuePair("interval year to month",CSharpDataType.@int),
+ new KeyValuePair("interval day to second",CSharpDataType.@int),
+
+ new KeyValuePair("number",CSharpDataType.@int),
+ new KeyValuePair("number",CSharpDataType.@float),
+ new KeyValuePair("number",CSharpDataType.@short),
+ new KeyValuePair("number",CSharpDataType.@byte),
+ new KeyValuePair("number",CSharpDataType.@double),
+ new KeyValuePair("number",CSharpDataType.@long),
+ new KeyValuePair("number",CSharpDataType.@bool),
+ new KeyValuePair("number",CSharpDataType.@decimal),
+ new KeyValuePair("number",CSharpDataType.Single),
+ new KeyValuePair("decimal",CSharpDataType.@decimal),
+ new KeyValuePair("decimal",CSharpDataType.Single),
+
+ new KeyValuePair("varchar",CSharpDataType.@string),
+ new KeyValuePair("varchar2",CSharpDataType.@string),
+ new KeyValuePair("nvarchar2",CSharpDataType.@string),
+ new KeyValuePair("xmltype",CSharpDataType.@string),
+ new KeyValuePair("char",CSharpDataType.@string),
+ new KeyValuePair("nchar",CSharpDataType.@string),
+ new KeyValuePair("clob",CSharpDataType.@string),
+ new KeyValuePair("long",CSharpDataType.@string),
+ new KeyValuePair("nclob",CSharpDataType.@string),
+ new KeyValuePair("rowid",CSharpDataType.@string),
+
+ new KeyValuePair("date",CSharpDataType.DateTime),
+ new KeyValuePair("timestamptz",CSharpDataType.DateTime),
+ new KeyValuePair("timestamp",CSharpDataType.DateTime),
+ new KeyValuePair("timestamp with local time zone",CSharpDataType.DateTime),
+ new KeyValuePair("timestamp with time zone",CSharpDataType.DateTime),
+
+ new KeyValuePair("float",CSharpDataType.@decimal),
+
+ new KeyValuePair("blob",CSharpDataType.byteArray),
+ new KeyValuePair("long raw",CSharpDataType.byteArray),
+ new KeyValuePair("longraw",CSharpDataType.byteArray),
+ new KeyValuePair("raw",CSharpDataType.byteArray),
+ new KeyValuePair("bfile",CSharpDataType.byteArray),
+ new KeyValuePair("varbinary",CSharpDataType.byteArray) };
+ public override List StringThrow
+ {
+ get
+ {
+ return new List() { "int32", "datetime", "decimal", "double", "byte" };
+ }
+ }
+ }
+}
diff --git a/Src/Asp.NetCore2/SqlSugar.OceanBaseForOracle/OceanBase/DbFirst/OceanBaseForOracleDbFirst.cs b/Src/Asp.NetCore2/SqlSugar.OceanBaseForOracle/OceanBase/DbFirst/OceanBaseForOracleDbFirst.cs
new file mode 100644
index 000000000..48e776e43
--- /dev/null
+++ b/Src/Asp.NetCore2/SqlSugar.OceanBaseForOracle/OceanBase/DbFirst/OceanBaseForOracleDbFirst.cs
@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SqlSugar.OceanBaseForOracle
+{
+ public class OceanBaseForOracleDbFirst : DbFirstProvider
+ {
+ }
+}
diff --git a/Src/Asp.NetCore2/SqlSugar.OceanBaseForOracle/OceanBase/DbMaintenance/OceanBaseForOracleDbMaintenance.cs b/Src/Asp.NetCore2/SqlSugar.OceanBaseForOracle/OceanBase/DbMaintenance/OceanBaseForOracleDbMaintenance.cs
new file mode 100644
index 000000000..6112badf5
--- /dev/null
+++ b/Src/Asp.NetCore2/SqlSugar.OceanBaseForOracle/OceanBase/DbMaintenance/OceanBaseForOracleDbMaintenance.cs
@@ -0,0 +1,582 @@
+using System;
+using System.Collections.Generic;
+using System.Data.Common;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SqlSugar.OceanBaseForOracle
+{
+ public class OceanBaseForOracleDbMaintenance : DbMaintenanceProvider
+ {
+ #region DML
+ protected override string GetDataBaseSql
+ {
+ get
+ {
+ throw new NotSupportedException();
+ }
+ }
+ protected override string GetColumnInfosByTableNameSql
+ {
+ get
+ {
+ throw new NotSupportedException();
+ }
+ }
+ protected override string GetTableInfoListSql
+ {
+ get
+ {
+ return @"SELECT table_name name ,
+ (select COMMENTS from user_tab_comments where t.table_name=table_name ) as Description
+
+ from user_tables t where
+ table_name!='HELP'
+ AND table_name NOT LIKE '%$%'
+ AND table_name NOT LIKE 'LOGMNRC_%'
+ AND table_name!='LOGMNRP_CTAS_PART_MAP'
+ AND table_name!='LOGMNR_LOGMNR_BUILDLOG'
+ AND table_name!='SQLPLUS_PRODUCT_PROFILE'
+ ";
+ }
+ }
+ protected override string GetViewInfoListSql
+ {
+ get
+ {
+ return @"select view_name name from user_views
+ WHERE VIEW_name NOT LIKE '%$%'
+ AND VIEW_NAME !='PRODUCT_PRIVS'
+ AND VIEW_NAME NOT LIKE 'MVIEW_%' ";
+ }
+ }
+ #endregion
+
+ #region DDL
+ protected override string IsAnyIndexSql
+ {
+ get
+ {
+ return "select count(1) from user_ind_columns where index_name=('{0}')";
+ }
+ }
+ protected override string CreateIndexSql
+ {
+ get
+ {
+ return "CREATE {3} INDEX Index_{0}_{2} ON {0}({1})";
+ }
+ }
+ protected override string AddDefaultValueSql
+ {
+ get
+ {
+ return "ALTER TABLE {0} MODIFY({1} DEFAULT '{2}')";
+ }
+ }
+ protected override string CreateDataBaseSql
+ {
+ get
+ {
+ return "CREATE DATABASE {0}";
+ }
+ }
+ protected override string AddPrimaryKeySql
+ {
+ get
+ {
+ return "ALTER TABLE {0} ADD CONSTRAINT {1} PRIMARY KEY({2})";
+ }
+ }
+ protected override string AddColumnToTableSql
+ {
+ get
+ {
+ return "ALTER TABLE {0} ADD ({1} {2}{3} {4} {5} {6})";
+ }
+ }
+ protected override string AlterColumnToTableSql
+ {
+ get
+ {
+ return "ALTER TABLE {0} modify ({1} {2}{3} {4} {5} {6}) ";
+ }
+ }
+ protected override string BackupDataBaseSql
+ {
+ get
+ {
+ return @"USE master;BACKUP DATABASE {0} TO disk = '{1}'";
+ }
+ }
+ protected override string CreateTableSql
+ {
+ get
+ {
+ return "CREATE TABLE {0}(\r\n{1})";
+ }
+ }
+ protected override string CreateTableColumn
+ {
+ get
+ {
+ return "{0} {1}{2} {3} {4} {5}";
+ }
+ }
+ protected override string TruncateTableSql
+ {
+ get
+ {
+ return "TRUNCATE TABLE {0}";
+ }
+ }
+ protected override string BackupTableSql
+ {
+ get
+ {
+ return "create table {1} as select * from {2} where ROWNUM<={0}";
+ }
+ }
+ protected override string DropTableSql
+ {
+ get
+ {
+ return "DROP TABLE {0}";
+ }
+ }
+ protected override string DropColumnToTableSql
+ {
+ get
+ {
+ return "ALTER TABLE {0} DROP COLUMN {1}";
+ }
+ }
+ protected override string DropConstraintSql
+ {
+ get
+ {
+ return "ALTER TABLE {0} DROP CONSTRAINT {1}";
+ }
+ }
+ protected override string RenameColumnSql
+ {
+ get
+ {
+ return "ALTER TABLE {0} rename column {1} to {2}";
+ }
+ }
+ protected override string AddColumnRemarkSql
+ {
+ get
+ {
+ return "comment on column {1}.{0} is '{2}'";
+ }
+ }
+
+ protected override string DeleteColumnRemarkSql
+ {
+ get
+ {
+ return "comment on column {1}.{0} is ''";
+ }
+ }
+
+ protected override string IsAnyColumnRemarkSql
+ {
+ get
+ {
+ return "select * from user_col_comments where Table_Name='{1}' AND COLUMN_NAME='{0}' order by column_name";
+ }
+ }
+
+ protected override string AddTableRemarkSql
+ {
+ get
+ {
+ return "comment on table {0} is '{1}'";
+ }
+ }
+
+ protected override string DeleteTableRemarkSql
+ {
+ get
+ {
+ return "comment on table {0} is ''";
+ }
+ }
+
+ protected override string IsAnyTableRemarkSql
+ {
+ get
+ {
+ return "select * from user_tab_comments where Table_Name='{0}'order by Table_Name";
+ }
+ }
+
+ protected override string RenameTableSql
+ {
+ get
+ {
+ return "alter table {0} rename to {1}";
+ }
+ }
+ protected override string IsAnyProcedureSql
+ {
+ get
+ {
+ return "SELECT COUNT(*) FROM user_objects WHERE OBJECT_TYPE = 'PROCEDURE' AND OBJECT_NAME ='{0}'";
+ }
+ }
+ #endregion
+
+ #region Check
+ protected override string CheckSystemTablePermissionsSql
+ {
+ get
+ {
+ return "select t.table_name from user_tables t where rownum=1";
+ }
+ }
+ #endregion
+
+ #region Scattered
+ protected override string CreateTableNull
+ {
+ get
+ {
+ return "";
+ }
+ }
+ protected override string CreateTableNotNull
+ {
+ get
+ {
+ return " NOT NULL ";
+ }
+ }
+ protected override string CreateTablePirmaryKey
+ {
+ get
+ {
+ return "PRIMARY KEY";
+ }
+ }
+ protected override string CreateTableIdentity
+ {
+ get
+ {
+ return "";
+ }
+ }
+ #endregion
+
+ #region Methods
+ public override List GetIndexList(string tableName)
+ {
+ var sql = $"SELECT index_name FROM user_ind_columns\r\nWHERE table_name = '{tableName}'";
+ return this.Context.Ado.SqlQuery(sql);
+ }
+ public override List GetProcList(string dbName)
+ {
+ var sql = $"SELECT OBJECT_NAME FROM ALL_OBJECTS WHERE OBJECT_TYPE = 'PROCEDURE' AND OWNER = '{dbName.ToUpper()}'";
+ return this.Context.Ado.SqlQuery(sql);
+ }
+ public override bool AddColumn(string tableName, DbColumnInfo columnInfo)
+ {
+ if (columnInfo.DataType == "varchar" && columnInfo.Length == 0)
+ {
+ columnInfo.DataType = "varchar2";
+ columnInfo.Length = 50;
+ }
+ return base.AddColumn(tableName, columnInfo);
+ }
+ public override bool CreateIndex(string tableName, string[] columnNames, bool isUnique = false)
+ {
+ string sql = string.Format(CreateIndexSql, tableName, string.Join(",", columnNames), string.Join("_", columnNames.Select(it => (it + "abc").Substring(0, 3))), isUnique ? "UNIQUE" : "");
+ this.Context.Ado.ExecuteCommand(sql);
+ return true;
+ }
+ public override bool AddDefaultValue(string tableName, string columnName, string defaultValue)
+ {
+ if (defaultValue == "''")
+ {
+ defaultValue = "";
+ }
+ if (defaultValue.ToLower().IsIn("sysdate"))
+ {
+ var template = AddDefaultValueSql.Replace("'", "");
+ string sql = string.Format(template, tableName, columnName, defaultValue);
+ this.Context.Ado.ExecuteCommand(sql);
+ return true;
+ }
+ else
+ {
+ return base.AddDefaultValue(tableName, columnName, defaultValue);
+ }
+ }
+ public override bool CreateDatabase(string databaseDirectory = null)
+ {
+ if (this.Context.Ado.IsValidConnection())
+ {
+ return true;
+ }
+ Check.ExceptionEasy("Oracle no support create database ", "Oracle不支持建库方法,请写有效连接字符串可以正常运行该方法。");
+ return true;
+ }
+ public override bool CreateDatabase(string databaseName, string databaseDirectory = null)
+ {
+ throw new NotSupportedException();
+ }
+ public override bool AddRemark(EntityInfo entity)
+ {
+ var db = this.Context;
+ var columns = entity.Columns.Where(it => it.IsIgnore == false).ToList();
+
+ foreach (var item in columns)
+ {
+ if (item.ColumnDescription != null)
+ {
+ //column remak
+ if (db.DbMaintenance.IsAnyColumnRemark(item.DbColumnName.ToUpper(IsUppper), item.DbTableName.ToUpper(IsUppper)))
+ {
+ db.DbMaintenance.DeleteColumnRemark(this.SqlBuilder.GetTranslationColumnName(item.DbColumnName), item.DbTableName.ToUpper(IsUppper));
+ db.DbMaintenance.AddColumnRemark(this.SqlBuilder.GetTranslationColumnName(item.DbColumnName), item.DbTableName.ToUpper(IsUppper), item.ColumnDescription);
+ }
+ else
+ {
+ db.DbMaintenance.AddColumnRemark(item.DbColumnName.ToUpper(IsUppper), item.DbTableName.ToUpper(IsUppper), item.ColumnDescription);
+ }
+ }
+ }
+
+ //table remak
+ if (entity.TableDescription != null)
+ {
+ if (db.DbMaintenance.IsAnyTableRemark(entity.DbTableName))
+ {
+ db.DbMaintenance.DeleteTableRemark(entity.DbTableName);
+ db.DbMaintenance.AddTableRemark(entity.DbTableName, entity.TableDescription);
+ }
+ else
+ {
+ db.DbMaintenance.AddTableRemark(entity.DbTableName, entity.TableDescription);
+ }
+ }
+ return true;
+ }
+ public override List GetColumnInfosByTableName(string tableName, bool isCache = true)
+ {
+ string cacheKey = "DbMaintenanceProvider.GetColumnInfosByTableName." + this.SqlBuilder.GetNoTranslationColumnName(tableName).ToLower();
+ cacheKey = GetCacheKey(cacheKey);
+ if (!isCache)
+ return GetColumnInfosByTableName(tableName);
+ else
+ return this.Context.Utilities.GetReflectionInoCacheInstance().GetOrCreate(cacheKey,
+ () =>
+ {
+ return GetColumnInfosByTableName(tableName);
+
+ });
+ }
+
+ private List GetColumnInfosByTableName(string tableName)
+ {
+ List columns = GetOracleDbType(tableName);
+ string sql = "select * /* " + Guid.NewGuid() + " */ from " + SqlBuilder.GetTranslationTableName(tableName) + " WHERE 1=2 ";
+ if (!this.GetTableInfoList(false).Any(it => it.Name == SqlBuilder.GetTranslationTableName(tableName).TrimStart('\"').TrimEnd('\"')))
+ {
+ sql = "select * /* " + Guid.NewGuid() + " */ from \"" + tableName + "\" WHERE 1=2 ";
+ }
+ this.Context.Utilities.RemoveCache>("DbMaintenanceProvider.GetFieldComment." + tableName);
+ this.Context.Utilities.RemoveCache>("DbMaintenanceProvider.GetPrimaryKeyByTableNames." + this.SqlBuilder.GetNoTranslationColumnName(tableName).ToLower());
+ var oldIsEnableLog = this.Context.Ado.IsEnableLogEvent;
+ this.Context.Ado.IsEnableLogEvent = false;
+ using (DbDataReader reader = (DbDataReader)this.Context.Ado.GetDataReader(sql))
+ {
+ this.Context.Ado.IsEnableLogEvent = oldIsEnableLog;
+ List result = new List();
+ var schemaTable = reader.GetSchemaTable();
+ foreach (System.Data.DataRow row in schemaTable.Rows)
+ {
+ DbColumnInfo column = new DbColumnInfo()
+ {
+ TableName = tableName,
+ DataType = row["DataType"].ToString().Replace("System.", "").Trim(),
+ IsNullable = (bool)row["AllowDBNull"],
+ //IsIdentity = (bool)row["IsAutoIncrement"],
+ ColumnDescription = GetFieldComment(tableName, row["ColumnName"].ToString()),
+ DbColumnName = row["ColumnName"].ToString(),
+ //DefaultValue = row["defaultValue"].ToString(),
+ IsPrimarykey = GetPrimaryKeyByTableNames(tableName).Any(it => it.Equals(row["ColumnName"].ToString(), StringComparison.CurrentCultureIgnoreCase)),
+ Length = row["ColumnSize"].ObjToInt(),
+ Scale = row["numericscale"].ObjToInt()
+ };
+ var current = columns.FirstOrDefault(it => it.DbColumnName.EqualCase(column.DbColumnName));
+ if (current != null)
+ {
+ column.OracleDataType = current.DataType;
+ if (current.DataType.EqualCase("number"))
+ {
+ column.Length = row["numericprecision"].ObjToInt();
+ column.Scale = row["numericscale"].ObjToInt();
+ column.DecimalDigits = row["numericscale"].ObjToInt();
+ if (column.Length == 38 && column.Scale == 0)
+ {
+ column.Length = 22;
+ }
+ }
+ }
+ result.Add(column);
+ }
+ return result;
+ }
+ }
+
+ private List GetOracleDbType(string tableName)
+ {
+ var sql0 = $@"select
+ t1.table_name as TableName,
+ t6.comments,
+ t1.column_id,
+ t1.column_name as DbColumnName,
+ t5.comments,
+ t1.data_type as DataType,
+ t1.data_length as Length,
+ t1.char_length,
+ t1.data_precision,
+ t1.data_scale,
+ t1.nullable,
+ t4.index_name,
+ t4.column_position,
+ t4.descend
+ from user_tab_columns t1
+ left join (select t2.table_name,
+ t2.column_name,
+ t2.column_position,
+ t2.descend,
+ t3.index_name
+ from user_ind_columns t2
+ left join user_indexes t3
+ on t2.table_name = t3.table_name and t2.index_name = t3.index_name
+ and t3.status = 'valid' and t3.uniqueness = 'unique') t4 --unique:唯一索引
+ on t1.table_name = t4.table_name and t1.column_name = t4.column_name
+ left join user_col_comments t5 on t1.table_name = t5.table_name and t1.column_name = t5.column_name
+ left join user_tab_comments t6 on t1.table_name = t6.table_name
+ where upper(t1.table_name)=upper('{tableName}')
+ order by t1.table_name, t1.column_id";
+
+ var columns = this.Context.Ado.SqlQuery(sql0);
+ return columns;
+ }
+
+ private List GetPrimaryKeyByTableNames(string tableName)
+ {
+ string cacheKey = "DbMaintenanceProvider.GetPrimaryKeyByTableNames." + this.SqlBuilder.GetNoTranslationColumnName(tableName).ToLower();
+ cacheKey = GetCacheKey(cacheKey);
+ return this.Context.Utilities.GetReflectionInoCacheInstance().GetOrCreate(cacheKey,
+ () =>
+ {
+ var oldIsEnableLog = this.Context.Ado.IsEnableLogEvent;
+ this.Context.Ado.IsEnableLogEvent = false;
+ string sql = @" select distinct cu.COLUMN_name KEYNAME from user_cons_columns cu, user_constraints au
+ where cu.constraint_name = au.constraint_name
+ and au.constraint_type = 'P' and au.table_name = '" + tableName.ToUpper(IsUppper) + @"'";
+ var pks = this.Context.Ado.SqlQuery(sql);
+ this.Context.Ado.IsEnableLogEvent = oldIsEnableLog;
+ return pks;
+ });
+ }
+
+ public string GetTableComment(string tableName)
+ {
+ string cacheKey = "DbMaintenanceProvider.GetTableComment." + tableName;
+ var comments = this.Context.Utilities.GetReflectionInoCacheInstance().GetOrCreate(cacheKey,
+ () =>
+ {
+ string sql = "SELECT COMMENTS FROM USER_TAB_COMMENTS WHERE TABLE_NAME =@tableName ORDER BY TABLE_NAME";
+ var oldIsEnableLog = this.Context.Ado.IsEnableLogEvent;
+ this.Context.Ado.IsEnableLogEvent = false;
+ var pks = this.Context.Ado.SqlQuery(sql, new { tableName = tableName.ToUpper(IsUppper) });
+ this.Context.Ado.IsEnableLogEvent = oldIsEnableLog;
+ return pks;
+ });
+ return comments.HasValue() ? comments.First() : "";
+ }
+
+ public string GetFieldComment(string tableName, string filedName)
+ {
+ string cacheKey = "DbMaintenanceProvider.GetFieldComment." + tableName;
+ var comments = this.Context.Utilities.GetReflectionInoCacheInstance().GetOrCreate(cacheKey,
+ () =>
+ {
+ string sql = "SELECT TABLE_NAME AS TableName, COLUMN_NAME AS DbColumnName,COMMENTS AS ColumnDescription FROM user_col_comments WHERE TABLE_NAME =@tableName ORDER BY TABLE_NAME";
+ var oldIsEnableLog = this.Context.Ado.IsEnableLogEvent;
+ this.Context.Ado.IsEnableLogEvent = false;
+ var pks = this.Context.Ado.SqlQuery(sql, new { tableName = tableName.ToUpper(IsUppper) });
+ this.Context.Ado.IsEnableLogEvent = oldIsEnableLog;
+ return pks;
+ });
+ return comments.HasValue() ? comments.First(it => it.DbColumnName.Equals(filedName, StringComparison.CurrentCultureIgnoreCase)).ColumnDescription : "";
+
+ }
+
+ public override bool CreateTable(string tableName, List columns, bool isCreatePrimaryKey = true)
+ {
+ if (columns.HasValue())
+ {
+ foreach (var item in columns)
+ {
+ if (item.DbColumnName.Equals("GUID", StringComparison.CurrentCultureIgnoreCase) && item.Length == 0)
+ {
+ item.Length = 50;
+ }
+ if (item.DataType == "varchar" && item.Length == 0)
+ {
+ item.Length = 50;
+ }
+ if (item.IsIdentity && this.Context.CurrentConnectionConfig?.MoreSettings?.EnableOracleIdentity == true)
+ {
+ item.DataType = "NUMBER GENERATED ALWAYS AS IDENTITY";
+ }
+ }
+ }
+ string sql = GetCreateTableSql(tableName, columns);
+ this.Context.Ado.ExecuteCommand(sql);
+ if (isCreatePrimaryKey)
+ {
+ var pkColumns = columns.Where(it => it.IsPrimarykey).ToList();
+ if (pkColumns.Count <= 1)
+ {
+ foreach (var item in pkColumns)
+ {
+ this.Context.DbMaintenance.AddPrimaryKey(tableName, item.DbColumnName);
+ }
+ }
+ else
+ {
+ this.Context.DbMaintenance.AddPrimaryKey(tableName, string.Join(",", pkColumns.Select(it => this.SqlBuilder.GetTranslationColumnName(it.DbColumnName)).ToArray()));
+ }
+ }
+ return true;
+ }
+ #endregion
+
+ #region Helper
+ public bool IsUppper
+ {
+ get
+ {
+ if (this.Context.CurrentConnectionConfig.MoreSettings == null)
+ {
+ return true;
+ }
+ else
+ {
+ return this.Context.CurrentConnectionConfig.MoreSettings.IsAutoToUpper == true;
+ }
+ }
+ }
+ #endregion
+ }
+}
diff --git a/Src/Asp.NetCore2/SqlSugar.OceanBaseForOracle/OceanBase/OceanBaseForOracleProvider.cs b/Src/Asp.NetCore2/SqlSugar.OceanBaseForOracle/OceanBase/OceanBaseForOracleProvider.cs
new file mode 100644
index 000000000..498961b44
--- /dev/null
+++ b/Src/Asp.NetCore2/SqlSugar.OceanBaseForOracle/OceanBase/OceanBaseForOracleProvider.cs
@@ -0,0 +1,345 @@
+using System;
+using System.Collections.Generic;
+using System.Data;
+using System.Data.Common;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Xml.Linq;
+using System.Data.Odbc;
+using System.Text.RegularExpressions;
+namespace SqlSugar.OceanBaseForOracle
+{
+ public class OceanBaseForOracleProvider : AdoProvider
+ {
+ public OceanBaseForOracleProvider() { }
+ public override IDbConnection Connection
+ {
+ get
+ {
+ if (base._DbConnection == null)
+ {
+ try
+ {
+ base._DbConnection = new OdbcConnection(base.Context.CurrentConnectionConfig.ConnectionString);
+ }
+ catch (Exception ex)
+ {
+ throw ex;
+ }
+ }
+ return base._DbConnection;
+ }
+ set
+ {
+ base._DbConnection = value;
+ }
+ }
+
+ public string SplitCommandTag => UtilConstants.ReplaceCommaKey.Replace("{", "").Replace("}", "");
+
+
+ public override object GetScalar(string sql, params SugarParameter[] parameters)
+ {
+ if (this.Context.Ado.Transaction != null)
+ {
+ return _GetScalar(sql, parameters);
+ }
+ else
+ {
+ try
+ {
+ this.Context.Ado.BeginTran();
+ var result = _GetScalar(sql, parameters);
+ this.Context.Ado.CommitTran();
+ return result;
+ }
+ catch (Exception ex)
+ {
+ this.Context.Ado.RollbackTran();
+ throw ex;
+ }
+ }
+ }
+
+ public override async Task