using System; using CYQ.Data.Table; using System.Data; using CYQ.Data.SQL; using System.IO; using System.Collections.Generic; using System.Text; namespace CYQ.Data.Tool { /// /// 数据库工具类[都是静态方法] /// public static partial class DBTool { private static StringBuilder _ErrorMsg = new StringBuilder(); /// /// 获取异常的信息 /// public static string ErrorMsg { get { return _ErrorMsg.ToString(); } set { _ErrorMsg.Length = 0; if (value != null) { _ErrorMsg.Append(value); } } } #region 库层面操作 /// /// 获取数据库链接的数据库类型 /// /// 链接配置Key或数据库链接语句 /// public static DataBaseType GetDataBaseType(string conn) { return ConnBean.Create(conn).ConnDataBaseType; } /// /// 获取指定数据库的数据类型 /// /// 单元格结构 /// 数据库类型 /// 数据库版本号 /// public static string GetDataType(MCellStruct ms, DataBaseType dalType, string version) { return DataType.GetDataType(ms, dalType, version); } /// /// 测试数据库链接语句 /// /// 链接配置Key或数据库链接语句 /// public static bool TestConn(string conn) { string msg; return TestConn(conn, out msg); } public static bool TestConn(string conn, out string msg) { bool result = false; try { DalBase helper = DalCreate.CreateDal(conn); result = helper.TestConn(AllowConnLevel.Master); if (result) { msg = helper.Version; } else { msg = helper.DebugInfo.ToString(); } helper.Dispose(); } catch (Exception err) { msg = err.Message; } return result; } #endregion #region 表的相关操作 #region 表是否存在 /// /// 是否存在(表 U、视图 V 存储过程 P) /// /// 名称 public static bool Exists(string name) { return Exists(name, null); } /// /// 是否存在(表 U、视图 V 存储过程 P) /// /// 名称 /// 表 U、视图 V 存储过程 P public static bool Exists(string name, string type) { return Exists(name, type, AppConfig.DB.DefaultConn); } /// /// 是否存在(表 U、视图 V 存储过程 P) /// /// 名称 /// 表 U、视图 V 存储过程 P /// 指定链接 /// public static bool Exists(string name, string type, string conn) { return CrossDB.Exists(name, type, conn); } #endregion #region 创建表语句 /// /// 为指定的表架构生成SQL(Create Table)语句 /// public static bool CreateTable(string tableName, MDataColumn columns) { return CreateTable(tableName, columns, AppConfig.DB.DefaultConn); } /// /// 为指定的表架构生成SQL(Create Table)语句 /// public static bool CreateTable(string tableName, MDataColumn columns, string conn) { if (string.IsNullOrEmpty(tableName) || tableName.Contains("(") && tableName.Contains(")")) { return false; } bool result = false; DataBaseType dalType = GetDataBaseType(conn); string dataBase = string.Empty; switch (dalType) { case DataBaseType.Txt: case DataBaseType.Xml: // string a, b, c; conn = AppConfig.GetConn(conn);// CYQ.Data.DAL.DalCreate.GetConnString(conn, out a, out b, out c); if (conn.ToLower().Contains(";ts=0"))//不写入表架构。 { //增加缓存 result = true; } else { tableName = Path.GetFileNameWithoutExtension(tableName); string fileName = NoSqlConnection.GetFilePath(conn) + tableName + ".ts"; result = columns.WriteSchema(fileName); dataBase = GetDBInfo(conn).DataBaseName; } break; default: #region MyRegion using (MProc proc = new MProc(null, conn)) { dataBase = proc.DataBaseName; try { proc.dalHelper.IsRecordDebugInfo = false || AppDebug.IsContainSysSql; proc.SetAopState(Aop.AopOp.CloseAll); proc.ResetProc(GetCreateTableSql(tableName, columns, proc.DataBaseType, proc.DataBaseVersion));//.Replace("\n", string.Empty) result = proc.ExeNonQuery() > -2; if (result) { //获取扩展说明 string descriptionSql = GetCreateTableDescriptionSql(tableName, columns, proc.DataBaseType).Replace("\r\n", " ").Trim(' ', ';'); if (!string.IsNullOrEmpty(descriptionSql)) { if (proc.DataBaseType == DataBaseType.Oracle) { foreach (string sql in descriptionSql.Split(';')) { proc.ResetProc(sql); if (proc.ExeNonQuery() == -2) { break; } } } else { proc.ResetProc(descriptionSql); proc.ExeNonQuery(); } } } } catch (Exception err) { Log.Write(err, LogType.DataBase); } finally { if (proc.RecordsAffected == -2) { _ErrorMsg.AppendLine("CreateTable:" + proc.DebugInfo); } } } #endregion break; } if (result) { CrossDB.Add(tableName, "U", conn);//修改缓存。 } return result; } /// /// 获取指定的表架构生成的SQL(Create Table)的说明语句 /// public static string GetCreateTableDescriptionSql(string tableName) { return GetCreateTableDescriptionSql(tableName, AppConfig.DB.DefaultConn); } public static string GetCreateTableDescriptionSql(string tableName, string conn) { MDataColumn mdc = GetColumns(tableName, conn); return GetCreateTableDescriptionSql(tableName, mdc, mdc.DataBaseType); } /// /// 获取指定的表架构生成的SQL(Create Table)的说明语句 /// public static string GetCreateTableDescriptionSql(string tableName, MDataColumn columns, DataBaseType dalType) { return SqlCreateForSchema.CreateTableDescriptionSql(tableName, columns, dalType); } /// /// 获取指定的表架构生成的SQL(Create Table)的说明语句 /// public static string GetCreateTableSql(string tableName) { return GetCreateTableSql(tableName, AppConfig.DB.DefaultConn); } public static string GetCreateTableSql(string tableName,string conn) { MDataColumn mdc = GetColumns(tableName, conn); return GetCreateTableSql(tableName, mdc, mdc.DataBaseType, mdc.DataBaseVersion); } /// /// 获取指定的表架构生成的SQL(Create Table)的说明语句 /// public static string GetCreateTableSql(string tableName, MDataColumn columns, DataBaseType dalType, string version) { return SqlCreateForSchema.CreateTableSql(tableName, columns, dalType, version); } internal static void CheckAndCreateOracleSequence(string seqName, string conn, string primaryKey, string tableName) { seqName = seqName.ToUpper(); using (DalBase db = DalCreate.CreateDal(conn)) { object o = db.ExeScalar(string.Format(ExistOracleSequence, seqName), false); if (db.RecordsAffected != -2 && (o == null || Convert.ToString(o) == "0")) { int startWith = 1; if (!string.IsNullOrEmpty(primaryKey)) { o = db.ExeScalar(string.Format(GetOracleMaxID, primaryKey, tableName), false); if (db.RecordsAffected != -2) { if (!int.TryParse(Convert.ToString(o), out startWith) || startWith < 1) { startWith = 1; } else { startWith++; } } } db.ExeNonQuery(string.Format(CreateOracleSequence, seqName, startWith), false); } if (db.RecordsAffected == -2) { _ErrorMsg.AppendLine("CheckAndCreateOracleSequence:" + db.DebugInfo.ToString()); } } } #endregion #region 修改表语句 /// /// 获取指定的表架构生成的SQL(Alter Table)的说明语句 /// public static string GetAlterTableSql(string tableName, MDataColumn columns) { return GetAlterTableSql(tableName, columns, AppConfig.DB.DefaultConn); } /// /// 获取指定的表架构生成的SQL(Alter Table)的说明语句 /// public static string GetAlterTableSql(string tableName, MDataColumn columns, string conn) { List sqlItems = SqlCreateForSchema.AlterTableSql(tableName, columns, conn); if (sqlItems.Count > 0) { StringBuilder sb = new StringBuilder(); foreach (string sql in sqlItems) { sb.AppendLine(sql); } sqlItems = null; return sb.ToString(); } return string.Empty; } /// /// 修改表的列结构 /// public static bool AlterTable(string tableName, MDataColumn columns) { return AlterTable(tableName, columns, AppConfig.DB.DefaultConn); } /// /// 修改表的列结构 /// /// 表名 /// 列结构 /// 数据库链接 /// public static bool AlterTable(string tableName, MDataColumn columns, string conn) { if (columns == null) { return false; } List sqls = SqlCreateForSchema.AlterTableSql(tableName, columns, conn); if (sqls.Count > 0) { DataBaseType dalType = DataBaseType.None; string database = string.Empty; using (MProc proc = new MProc(null, conn)) { dalType = proc.DataBaseType; database = proc.dalHelper.DataBaseName; proc.SetAopState(Aop.AopOp.CloseAll); if (proc.DataBaseType == DataBaseType.MsSql) { proc.BeginTransation();//仅对mssql有效。 } foreach (string sql in sqls) { proc.ResetProc(sql); if (proc.ExeNonQuery() == -2) { proc.RollBack(); _ErrorMsg.AppendLine("AlterTable:" + proc.DebugInfo); Log.Write(proc.DebugInfo, LogType.DataBase); return false; } } proc.EndTransation(); } RemoveCache(tableName, conn); return true; } return false; } #endregion #region 删除表语句 /// /// 移除一张表 /// /// public static bool DropTable(string tableName) { return DropTable(tableName, AppConfig.DB.DefaultConn); } /// /// 移除一张表 /// 数据库链接 /// public static bool DropTable(string tableName, string conn) { bool result = false; string key = string.Empty; using (DalBase helper = DalCreate.CreateDal(conn)) { DataBaseType dalType = helper.DataBaseType; switch (dalType) { case DataBaseType.Txt: case DataBaseType.Xml: string folder = helper.Con.DataSource + Path.GetFileNameWithoutExtension(tableName); string path = folder + ".ts"; try { if (File.Exists(path)) { result = IOHelper.Delete(path); } path = folder + (dalType == DataBaseType.Txt ? ".txt" : ".xml"); if (File.Exists(path)) { result = IOHelper.Delete(path); } } catch { } break; default: result = helper.ExeNonQuery("drop table " + Keyword(tableName, dalType), false) != -2; if (result) { //处理表相关的元数据和数据缓存。 RemoveCache(tableName, conn); } break; } if (helper.RecordsAffected == -2) { _ErrorMsg.AppendLine(helper.DebugInfo.ToString()); } } if (result) { //处理数据库表字典缓存 CrossDB.Remove(tableName, "U", conn); } return result; } #endregion #endregion #region 获取结构 /// /// 获取表列架构 /// public static MDataColumn GetColumns(Type typeInfo) { return TableSchema.GetColumnByType(typeInfo); } /// /// 获取表列架构 /// /// 表名 public static MDataColumn GetColumns(object tableNameObj) { string conn = string.Empty; if (tableNameObj is Enum) { conn = CrossDB.GetConnByEnum(tableNameObj as Enum); } return GetColumns(Convert.ToString(tableNameObj), conn); } /// /// 获取表列架构(链接错误时,抛异常) /// /// 表名 /// 数据库链接 /// 出错时的错误信息 /// public static MDataColumn GetColumns(string tableName, string conn, out string errInfo) { errInfo = string.Empty; try { return TableSchema.GetColumns(tableName, conn); } catch (Exception err) { errInfo = err.Message; return null; } } /// /// 获取表列架构 /// /// 表名 /// 数据库链接 /// public static MDataColumn GetColumns(string tableName, string conn) { string err; return GetColumns(tableName, conn, out err); } #endregion #region 其它操作 //private static List flag = new List(2); //internal static void CreateSelectBaseProc(DalType dal, string conn) //{ // try // { // switch (dal) // { // //case DalType.Oracle: // // if (!flag.Contains("oracle")) // // { // // flag.Add("oracle"); // // using (DbBase db = DalCreate.CreateDal(conn)) // // { // // db.AllowRecordSql = false; // // object o = db.ExeScalar(string.Format(ExistOracle.Replace("TABLE", "PROCEDURE"), "MyPackage.SelectBase"), false); // // if (o != null && Convert.ToInt32(o) < 1) // // { // // db.ExeNonQuery(SqlPager.GetPackageHeadForOracle(), false); // // db.ExeNonQuery(SqlPager.GetPackageBodyForOracle(), false); // // } // // } // // } // // break; // case DalType.MsSql: // if (!flag.Contains("sql")) // { // flag.Add("sql");//考虑到一个应用不太可能同时使用mssql的不同版本,只使用一个标识。 // using (DbBase db = DalCreate.CreateDal(conn)) // { // db.IsRecordDebugInfo = false; // object o = null; // if (!db.Version.StartsWith("08")) // { // // o = db.ExeScalar(string.Format(Exist2000.Replace("U", "P"), "SelectBase"), false); // // if (o != null && Convert.ToInt32(o) < 1) // // { // // db.ExeNonQuery(SqlPager.GetSelectBaseForSql2000(), false); // // } // //} // //else // //{ // o = db.ExeScalar(string.Format(TableSchema.Exist2005, "SelectBase", "P"), false); // if (o != null && Convert.ToInt32(o) < 1) // { // db.ExeNonQuery(SqlCreateForPager.GetSelectBaseForSql2005(), false); // } // } // } // } // break; // } // } // catch (Exception err) // { // Log.Write(err, LogType.DataBase); // } //} /// /// 为字段或表名添加关键字标签:如[],''等符号 /// /// 表名或字段名 /// 数据类型 /// public static string Keyword(string name, DataBaseType dalType) { return SqlFormat.Keyword(name, dalType); } /// /// 取消字段或表名添加关键字标签:如[],''等符号 /// /// 表名或字段名 public static string NotKeyword(string name) { return SqlFormat.NotKeyword(name); } /// /// 将各数据库默认值格式化成标准值,将标准值还原成各数据库默认值 /// /// [0:转成标准值],[1:转成各数据库值] /// public static string FormatDefaultValue(DataBaseType dalType, object value, int flag, SqlDbType sqlDbType) { return SqlFormat.FormatDefaultValue(dalType, value, flag, sqlDbType); } #endregion private static void RemoveCache(string tableName, string conn) { //清缓存 string key = Cache.CacheManage.GetKey(Cache.CacheKeyType.Schema, tableName, conn); Cache.CacheManage.LocalInstance.Remove(key); key = Cache.CacheManage.GetKey(Cache.CacheKeyType.AutoCache, tableName, conn); Cache.AutoCache.ReadyForRemove(key); } } public static partial class DBTool { /// /// 获取配置项中所有的数据库列表 /// public static Dictionary DataBases { get { return DBSchema.DBScheams; } } /// /// 获取单个数据库信息 /// /// public static DBInfo GetDBInfo(string conn) { return DBSchema.GetSchema(conn); } public static TableInfo GetTableInfo(string tableName) { return CrossDB.GetTableInfoByName(tableName); } public static TableInfo GetTableInfo(string tableName, string conn) { return CrossDB.GetTableInfoByName(tableName, conn); } } public static partial class DBTool { internal const string ExistOracleSequence = "SELECT count(*) FROM All_Sequences where Sequence_name='{0}'"; internal const string CreateOracleSequence = "create sequence {0} start with {1} increment by 1"; internal const string GetOracleMaxID = "select max({0}) from {1}"; } }