public Dictionary <string, OracleTableInfo> GetAllTable(OracleDBUtil dbUtil, string schema, string testModelTable = "") { // ======================================================= // 查詢 所有的欄位資訊 // ======================================================= // 兜組SQL var columnsQSql = new StringBuilder(); columnsQSql.Append("SELECT col.OWNER, "); columnsQSql.Append(" col.TABLE_NAME, "); columnsQSql.Append(" tabComt.COMMENTS AS TABLE_COMMENTS, "); columnsQSql.Append(" col.COLUMN_ID, "); columnsQSql.Append(" col.COLUMN_NAME, "); columnsQSql.Append(" col.DATA_TYPE, "); columnsQSql.Append(" col.DATA_LENGTH, "); columnsQSql.Append(" col.DATA_PRECISION, "); columnsQSql.Append(" col.DATA_SCALE, "); columnsQSql.Append(" col.DATA_DEFAULT, "); columnsQSql.Append(" col.CHAR_LENGTH, "); columnsQSql.Append(" col.NULLABLE, "); columnsQSql.Append(" colComt.COMMENTS "); columnsQSql.Append("FROM ALL_TAB_COLUMNS col "); //columnsQSql.Append(" JOIN ALL_TABLES tab "); //columnsQSql.Append(" ON col.OWNER = tab.OWNER "); //columnsQSql.Append(" AND col.TABLE_NAME = tab.TABLE_NAME "); columnsQSql.Append(" LEFT JOIN ALL_COL_COMMENTS colComt "); columnsQSql.Append(" ON col.OWNER = colComt.Owner "); columnsQSql.Append(" AND col.TABLE_NAME = colComt.TABLE_NAME "); columnsQSql.Append(" AND col.COLUMN_NAME = colComt.COLUMN_NAME "); columnsQSql.Append(" LEFT JOIN sys.USER_TAB_COMMENTS tabComt "); columnsQSql.Append(" ON tabComt.TABLE_TYPE in ('TABLE','VIEW') "); //改為連 View 一起撈 columnsQSql.Append(" AND tabComt.TABLE_NAME = col.TABLE_NAME "); columnsQSql.Append("WHERE col.OWNER = '" + schema + "' "); // 測試縮限範圍 if (StringUtil.NotEmpty(testModelTable)) { columnsQSql.Append("AND col.TABLE_NAME = '" + testModelTable + "' "); } columnsQSql.Append("ORDER BY col.TABLE_NAME, "); columnsQSql.Append(" col.COLUMN_ID "); // 查詢所有的欄位List var allColumnList = dbUtil.Query(columnsQSql.ToString()); // 依據 table 分類 var tableColumnProcResult = Process(allColumnList); // ======================================================= // 查詢 所有的欄位資訊 // ======================================================= var pKeyQSql = new StringBuilder(); pKeyQSql.Append("SELECT C.OWNER, "); pKeyQSql.Append(" C.TABLE_NAME, "); pKeyQSql.Append(" D.POSITION, "); pKeyQSql.Append(" D.COLUMN_NAME "); pKeyQSql.Append("FROM ALL_CONSTRAINTS C "); pKeyQSql.Append(" JOIN ALL_CONS_COLUMNS D "); pKeyQSql.Append(" ON C.OWNER = D.OWNER "); pKeyQSql.Append(" AND C.CONSTRAINT_NAME = D.CONSTRAINT_NAME "); pKeyQSql.Append("WHERE C.CONSTRAINT_TYPE = 'P' "); pKeyQSql.Append(" AND C.OWNER = '"+ schema + "' "); // 測試縮限範圍 if (StringUtil.NotEmpty(testModelTable)) { columnsQSql.Append("AND C.TABLE_NAME = '" + testModelTable + "' "); } pKeyQSql.Append("ORDER BY C.TABLE_NAME, "); pKeyQSql.Append(" D.POSITION "); var allPKeyColumnList = dbUtil.Query(pKeyQSql.ToString()); // 依據 table 分類 var pkColumnProcResult = Process(allPKeyColumnList); // ======================================================= // 組 tableInfo // ======================================================= var tableInfoMap = new Dictionary <string, OracleTableInfo>(); foreach (var tableName in tableColumnProcResult.ColumnInfoListByTableName.Keys) { var tableInfo = new OracleTableInfo(); // 一般欄位 tableInfo.ColumnDataMapList = tableColumnProcResult.ColumnInfoListByTableName[tableName]; tableInfo.ColumnDataMapByColName = tableColumnProcResult.ColumnInfoByColNameTableName[tableName]; tableInfo.ColumnNameSet = tableColumnProcResult.ColumnNameSetByTableName[tableName]; // PK欄位 if (pkColumnProcResult.ColumnInfoListByTableName.ContainsKey(tableName)) { tableInfo.PKeyDataMapList = pkColumnProcResult.ColumnInfoListByTableName[tableName]; tableInfo.PKeySet = pkColumnProcResult.ColumnNameSetByTableName[tableName]; } else { tableInfo.PKeyDataMapList = new List <IDictionary <string, object> >(); tableInfo.PKeySet = new List <string>(); } // PUT tableInfoMap.Add(tableName, tableInfo); } return(tableInfoMap); }
public void proc( string OUTPUT_PTAH, string schema, string classNamespace, string classPrefix, string nameMapClassName, OracleDBUtil dbUtil, string testModelTable = "" ) { var tb = new OracleTableInfo(); var fileUtil = new FileUtil(); Console.WriteLine("讀取 table 資訊"); var tableInfoList = tb.GetAllTable(dbUtil, schema, testModelTable); Console.WriteLine("讀取完成!: " + tableInfoList.Count); if (testModelTable.NotEmpty() && tableInfoList.Count == 0) { throw new Exception("找不到指定的 Table"); } foreach (KeyValuePair <string, OracleTableInfo> table in tableInfoList) { //======================================= //取得 table 資料 //======================================= //table 代號 var tableName = table.Key; //OracleTableInfo var tableInfo = table.Value; //不存在column資料時跳過 if (tableInfo.ColumnDataMapList.Count < 1) { continue; } //table 註解 var tableComments = prepareStr(replaceBreakLine(tableInfo.ColumnDataMapList[0]["TABLE_COMMENTS"] + "")).Replace(System.Environment.NewLine, ""); //class Name = var className = classPrefix + StringUtil.Convert2CamelCase(tableName) + ""; //======================================= //兜組 base class 代碼 //======================================= //TBMODEL var tbModelContent = new StringBuilder(); tbModelContent.AppendLine("using System;"); tbModelContent.AppendLine("using System.ComponentModel;"); tbModelContent.AppendLine("using System.ComponentModel.DataAnnotations;"); tbModelContent.AppendLine("using System.ComponentModel.DataAnnotations.Schema;"); tbModelContent.AppendLine("using rbt.util.db.model;"); tbModelContent.AppendLine("using rbt.DataAnnotations.Validation;"); tbModelContent.AppendLine(""); tbModelContent.AppendLine("namespace " + classNamespace); tbModelContent.AppendLine("{"); tbModelContent.AppendLine(" /// <summary>"); tbModelContent.AppendLine(" /// [" + tableName + " " + tableComments + "] table model"); tbModelContent.AppendLine(" /// <summary>"); tbModelContent.AppendLine(" [Table(\"" + tableName + "\")]"); tbModelContent.AppendLine(" [DisplayName(\"" + tableComments + "\")]"); tbModelContent.AppendLine(" public class " + className + " : BaseDBEntity"); tbModelContent.AppendLine(" {"); //validator var validatorContent = new StringBuilder(); validatorContent.AppendLine("using System;"); validatorContent.AppendLine("using System.ComponentModel;"); validatorContent.AppendLine("using System.ComponentModel.DataAnnotations;"); validatorContent.AppendLine(""); validatorContent.AppendLine("namespace " + classNamespace + ".validator"); validatorContent.AppendLine("{"); validatorContent.AppendLine(" /// <summary>"); validatorContent.AppendLine(" /// [" + tableName + " " + tableComments + "] table model validator"); validatorContent.AppendLine(" /// <summary>"); validatorContent.AppendLine(" [DisplayName(\"" + tableComments + " 欄位驗證\")]"); validatorContent.AppendLine(" public class " + className + "Validator"); validatorContent.AppendLine(" {"); var columnInfoContent = new StringBuilder(); foreach (Dictionary <string, object> item in tableInfo.ColumnDataMapList) { //"COLUMN_NAME" string columnName = prepareStr(StringUtil.SafeTrim(item["COLUMN_NAME"])); //"COMMENTS" string orgComments = replaceBreakLine(StringUtil.SafeTrim(item["COMMENTS"])); string comments = prepareStr(orgComments); columnInfoContent.AppendLine(" //" + columnName + "\t" + comments); } tbModelContent.AppendLine(); tbModelContent.AppendLine(columnInfoContent.ToString()); tbModelContent.AppendLine(); foreach (Dictionary <string, object> item in tableInfo.ColumnDataMapList) { //===================================================== // 取得欄位參數 //===================================================== //"COLUMN_NAME" string columnName = prepareStr(StringUtil.SafeTrim(item["COLUMN_NAME"])); //"DATA_TYPE" string dataType = StringUtil.SafeTrim(item["DATA_TYPE"]); //"COMMENTS" string orgComments = replaceBreakLine(StringUtil.SafeTrim(item["COMMENTS"])); string comments = prepareStr(orgComments); //DATA_LENGTH int dataLenght = int.Parse(StringUtil.SafeTrim(item["DATA_LENGTH"])); if ("NUMBER".Equals(dataType) && StringUtil.NotEmpty(item["DATA_PRECISION"])) { dataLenght = int.Parse(StringUtil.SafeTrim(item["DATA_PRECISION"])); } //"DATA_SCALE" int dataScale = int.Parse(StringUtil.SafeTrim(item["DATA_SCALE"], "0")); //額外訊息 var ExtInfoList = this.parseExtInfo(orgComments); //===================================================== // TBModel //===================================================== tbModelContent.AppendLine(" /// <summary>"); tbModelContent.AppendLine(" /// " + columnName + " " + orgComments); tbModelContent.AppendLine(" /// <summary>"); //DisplayName tbModelContent.AppendLine(" [DisplayName(\"" + (StringUtil.IsEmpty(comments) ? "未設定" : comments) + "\")]"); //NULLABLE //if (!"Y".Equals(StringUtil.SafeTrim(item["NULLABLE"]))) //{ // content.AppendLine(" [Required]"); //} //StringLength tbModelContent.Append(GetLengthAttr(dataType, StringUtil.SafeTrim(item["CHAR_LENGTH"]), comments)); //NumberValidtion tbModelContent.Append(GetNumberValidate(dataType, StringUtil.SafeTrim(item["DATA_PRECISION"]), StringUtil.SafeTrim(item["DATA_SCALE"]), comments)); //other Attribute tbModelContent.Append(prepareAttribute(orgComments)); //[Key] if (tableInfo.PKeySet.Contains(columnName)) { tbModelContent.AppendLine(" [Key]"); } tbModelContent.AppendLine(" public " + getType(dataType, dataLenght, dataScale, tableName + "." + columnName) + " " + columnName); tbModelContent.AppendLine(" {"); tbModelContent.AppendLine(" get { return _" + columnName + "; }"); tbModelContent.AppendLine(" set { if (!this.GetModeifyField().Contains(\"" + columnName + "\")) this.GetModeifyField().Add(\"" + columnName + "\"); _" + columnName + " = value; }"); tbModelContent.AppendLine(" }"); tbModelContent.AppendLine(" private " + getType(dataType, dataLenght, dataScale, tableName + "." + columnName) + " _" + columnName + " { get; set; }"); tbModelContent.AppendLine(""); //===================================================== // TBModel validator //===================================================== validatorContent.AppendLine(" /// <summary>"); validatorContent.AppendLine(" /// " + columnName + " " + orgComments); validatorContent.AppendLine(" /// <summary>"); //[Required] validatorContent.AppendLine(" [Required]"); validatorContent.AppendLine(" public " + getType(dataType, dataLenght, dataScale, tableName + "." + columnName) + " " + columnName + " { get; set; }"); validatorContent.AppendLine(""); //處理日期轉換欄位 if ((("varchar2".Equals(dataType) && dataLenght == 7) || ("nvarchar2".Equals(dataType) && dataLenght == 14)) && (columnName.ToLower().IndexOf("date") >= 0 || columnName.ToLower().IndexOf("day") >= 0)) { validatorContent.AppendLine(" /// <summary>"); validatorContent.AppendLine(" /// " + columnName + " " + comments + ": 西元日期轉換擴充欄位"); validatorContent.AppendLine(" /// </summary>"); validatorContent.AppendLine(" [Required]"); validatorContent.AppendLine(" public string " + columnName + "_AD { get; set; }"); validatorContent.AppendLine(""); } } tbModelContent.AppendLine(" /// <summary>"); tbModelContent.AppendLine(" /// 回傳 Table 名稱"); tbModelContent.AppendLine(" /// <summary>"); tbModelContent.AppendLine(" public override string GetTableName()"); tbModelContent.AppendLine(" {"); tbModelContent.AppendLine(" return \"" + tableName + "\";"); tbModelContent.AppendLine(" }"); tbModelContent.AppendLine(" "); tbModelContent.AppendLine(" }"); //content.AppendLine("}"); tbModelContent.AppendLine(""); //======================================= //擴充 model //======================================= tbModelContent.AppendLine(" /// <summary>"); tbModelContent.AppendLine(" /// [" + tableName + " " + tableComments + "] 擴充 model"); tbModelContent.AppendLine(" /// </summary>"); tbModelContent.AppendLine(" public class " + className + "Ext : " + className); tbModelContent.AppendLine(" {"); foreach (Dictionary <string, object> item in tableInfo.ColumnDataMapList) { //"COLUMN_NAME" string columnName = prepareStr(StringUtil.SafeTrim(item["COLUMN_NAME"])); //"DATA_TYPE" string dataType = StringUtil.SafeTrim(item["DATA_TYPE"]).ToLower(); //"COMMENTS" string orgComments = replaceBreakLine(StringUtil.SafeTrim(item["COMMENTS"])); string comments = prepareStr(orgComments); //額外訊息 var ExtInfoList = this.parseExtInfo(orgComments); //DATA_LENGTH int dataLenght = int.Parse(StringUtil.SafeTrim(item["DATA_LENGTH"])); //處理日期轉換欄位 if ((("varchar2".Equals(dataType) && dataLenght == 7) || ("nvarchar2".Equals(dataType) && dataLenght == 14)) && (columnName.ToLower().IndexOf("date") >= 0 || columnName.ToLower().IndexOf("day") >= 0)) { tbModelContent.AppendLine(" /// <summary>"); tbModelContent.AppendLine(" /// " + columnName + " " + comments + ": 西元日期轉換擴充欄位"); tbModelContent.AppendLine(" /// </summary>"); //DisplayName tbModelContent.AppendLine(" [DisplayName(\"" + (StringUtil.IsEmpty(comments) ? "未設定" : comments) + "\")]"); tbModelContent.AppendLine(" public string " + columnName + "_AD "); tbModelContent.AppendLine(" {"); tbModelContent.AppendLine(" get { return HelperUtil.DateTimeToString(TesnUtil.TransTwToDateTime(this." + columnName + ", \"\")); }"); tbModelContent.AppendLine(" set { this." + columnName + " = HelperUtil.DateTimeToTwString(HelperUtil.TransToDateTime(value), \"\"); }"); tbModelContent.AppendLine(" }"); tbModelContent.AppendLine(""); } //電話 if (ExtInfoList.IndexOf("PHONE") >= 0) { tbModelContent.AppendLine(" /// <summary>"); tbModelContent.AppendLine(" /// " + columnName + " " + comments + ": 電話號碼 擴充資料欄位"); tbModelContent.AppendLine(" /// </summary>"); tbModelContent.AppendLine(" public PhoneNumberModel " + columnName + "_PHONE "); tbModelContent.AppendLine(" {"); tbModelContent.AppendLine(" get { return PhoneNumberModel.Parse(this." + columnName + "); }"); tbModelContent.AppendLine(" set { this." + columnName + " = value.ToString(); }"); tbModelContent.AppendLine(" }"); tbModelContent.AppendLine(""); } //手機 if (ExtInfoList.IndexOf("MOBILE") >= 0) { tbModelContent.AppendLine(" /// <summary>"); tbModelContent.AppendLine(" /// " + columnName + " " + comments + ": 手機號碼 擴充資料欄位"); tbModelContent.AppendLine(" /// </summary>"); tbModelContent.AppendLine(" public MobileNumberModel " + columnName + "_MOBILE "); tbModelContent.AppendLine(" {"); tbModelContent.AppendLine(" get { return MobileNumberModel.Parse(this." + columnName + "); }"); tbModelContent.AppendLine(" set { this." + columnName + " = value.ToString(); }"); tbModelContent.AppendLine(" }"); tbModelContent.AppendLine(""); } //增加顯示存放欄位 if (ExtInfoList.IndexOf("SHOW_TEXT") >= 0) { tbModelContent.AppendLine(" /// <summary>"); tbModelContent.AppendLine(" /// " + columnName + " " + comments + ": 轉文字擴充欄位"); tbModelContent.AppendLine(" /// </summary>"); tbModelContent.AppendLine(" public string " + columnName + "_SHOW_TEXT { get; set; }"); tbModelContent.AppendLine(""); } //CHECKBOX foreach (string extInfo in ExtInfoList) { var currExtInfo = (extInfo + "").Trim(); if (currExtInfo.IndexOf("CHECKBOX:") >= 0) { var currParams = (currExtInfo + "").Trim().Split(':'); if (currParams.Length < 2) { throw new Exception(columnName + "欄位的 【CHECKBOX:】設定錯誤"); } tbModelContent.AppendLine(" /// <summary>"); tbModelContent.AppendLine(" /// " + columnName + " " + comments + ": CHECKBOX 擴充資料欄位"); tbModelContent.AppendLine(" /// </summary>"); tbModelContent.AppendLine(" public CheckBoxModel " + columnName + "_CHECKBOX "); tbModelContent.AppendLine(" {"); tbModelContent.AppendLine(" get { return new CheckBoxModel(base." + columnName + ", \"" + currParams[1] + "\"); }"); tbModelContent.AppendLine(" set { this." + columnName + " = value.Value; }"); tbModelContent.AppendLine(" }"); tbModelContent.AppendLine(""); } } //CHECKBOX foreach (string extInfo in ExtInfoList) { var currExtInfo = (extInfo + "").Trim(); if (currExtInfo.StartsWith("ENUM:")) { currExtInfo = currExtInfo.Substring(5); var currParams = (currExtInfo + "").Trim().SplitToList(","); tbModelContent.AppendLine(" /// <summary>"); tbModelContent.AppendLine(" /// " + columnName + " " + comments + ": 參數值擴充欄位"); tbModelContent.AppendLine(" /// </summary>"); tbModelContent.AppendLine(" public enum " + columnName + "_ENUM "); tbModelContent.AppendLine(" {"); for (int paramIndex = 0; paramIndex < currParams.Count; paramIndex++) { var parma = currParams[paramIndex]; //空白時不處理 if (string.IsNullOrEmpty(parma)) { continue; } //分割代號與說明 var paramCols = (parma + "").Trim().SplitToList("-"); if (paramCols.Count < 2) { throw new Exception(columnName + "欄位的 【ENUM:】設定錯誤 ex: 【ENUM:A-依選手(個人/組),B-依評審項目】"); } for (int colIndex = 0; colIndex < paramCols.Count; colIndex++) { paramCols[colIndex] = paramCols[colIndex].Trim(); if (paramCols[colIndex].Length == 0) { throw new Exception(columnName + "欄位的 【ENUM:】設定錯誤, 項目為空"); } } tbModelContent.AppendLine(" /// <summary>"); tbModelContent.AppendLine(" /// " + paramCols[1]); tbModelContent.AppendLine(" /// </summary>"); tbModelContent.AppendLine(" " + paramCols[0] + " = " + paramIndex + ((paramIndex < currParams.Count - 1) ? "," : "")); if (paramIndex < currParams.Count - 1) { tbModelContent.AppendLine(""); } } tbModelContent.AppendLine(" }"); tbModelContent.AppendLine(""); } } } tbModelContent.AppendLine(" }"); tbModelContent.AppendLine("}"); tbModelContent.AppendLine(""); validatorContent.AppendLine(" }"); validatorContent.AppendLine("}"); validatorContent.AppendLine(""); //輸出 TbModel fileUtil.WriteToFile(tbModelContent.ToString(), OUTPUT_PTAH + "/Models/Entities/" + className + ".cs"); //輸出 Validator fileUtil.WriteToFile(validatorContent.ToString(), OUTPUT_PTAH + "/Models/Entities/validator/" + className + "Validator.cs"); //Console.WriteLine(OUTPUT_PTAH + "/" + className + ".cs"); //StaticCodeMap.TableName } }
//private string _testTable = ""; /// <summary> /// /// </summary> /// <param name="sourceDb"></param> /// <param name="sourceSchema"></param> /// <param name="targetDb"></param> /// <param name="targetSchema"></param> /// <param name="resultFilePath"></param> /// <param name="resultFileName"></param> public OracleDif( OracleDBUtil sourceDb, string sourceSchema, OracleDBUtil targetDb, string targetSchema, string resultFilePath, string resultFileName) { //FileUtil fu = new FileUtil(); var fu = new StringBuilder(); var tb = new OracleTableInfo(); // ============================================================== // 取得資料庫的 Schema 資訊 // ============================================================== // 取得來源的table Schema 資料 Console.WriteLine("取得來源資料庫 Schema.."); var sourceTableInfoMap = tb.GetAllTable(sourceDb, sourceSchema); // System.out.println(new BeanUtil().showContent(sourceTableInfoMap)); // 取得來源的table Schema 資料 Console.WriteLine("取得目標資料庫 Schema.."); var targetTableInfoMap = tb.GetAllTable(targetDb, targetSchema); Console.WriteLine("比對中.."); // ============================================================== // 比對缺少的 TABLE // ============================================================== var firstAddFlag = true; foreach (var tableName in sourceTableInfoMap.Keys) { if (!targetTableInfoMap.ContainsKey(tableName)) { Console.WriteLine("目標缺少 TABLE :[" + tableName + "]"); if (firstAddFlag) { fu.AppendLine("/*==============================================================*/"); fu.AppendLine("/* 新增 Table*/"); fu.AppendLine("/*==============================================================*/"); firstAddFlag = false; } // 產生 create sql var sourceTableInfo = sourceTableInfoMap[tableName]; fu.AppendLine(GanCreateSql(targetSchema, tableName, sourceTableInfo.ColumnDataMapList, sourceTableInfo.PKeySet)); } } // ============================================================== // 各 table 欄位比對 // ============================================================== foreach (var tableName in sourceTableInfoMap.Keys) { // 目標無此 table 時跳過 if (!targetTableInfoMap.ContainsKey(tableName)) { continue; } // 取得來源 TableInfo var sourceTableInfo = sourceTableInfoMap[tableName]; // 取得目標 TableInfo var targetTableInfo = targetTableInfoMap[tableName]; // 新增欄位 var addSql = DiffAddColumn(targetSchema, tableName, sourceTableInfo.ColumnDataMapList, targetTableInfo.ColumnNameSet); // 修改欄位 var modifySql = DiffModifyColumn(targetSchema, tableName, sourceTableInfo.ColumnDataMapByColName, targetTableInfo.ColumnDataMapByColName); if (StringUtil.NotEmpty(addSql) || StringUtil.NotEmpty(modifySql)) { fu.AppendLine("/*==============================================================*/"); fu.AppendLine("/* 異動 Table : " + tableName + " */"); fu.AppendLine("/*==============================================================*/"); fu.AppendLine(addSql); fu.AppendLine(modifySql); } } // ============================================================== // 反向比對 // ============================================================== //FileUtil reFu = new FileUtil(); var reFu = new StringBuilder(); foreach (var tableName in targetTableInfoMap.Keys) { // 比對缺少TABLE if (!sourceTableInfoMap.ContainsKey(tableName)) { reFu.AppendLine("--來源缺少 TABLE :[" + tableName + "]"); continue; } // 比對缺少欄位 // 取得來源 TableInfo var sourceTableInfo = sourceTableInfoMap[tableName]; // 取得目標 TableInfo var targetTableInfo = targetTableInfoMap[tableName]; foreach (var columnName in targetTableInfo.ColumnNameSet) { if (!sourceTableInfo.ColumnNameSet.Contains(columnName)) { reFu.AppendLine("--來源 TABLE " + tableName + " 缺少欄位 :[" + columnName + "]"); } } } if (StringUtil.NotEmpty(fu.ToString())) { fu.AppendLine("/*==============================================================*/"); fu.AppendLine("/* 反向比對差異部分 */"); fu.AppendLine("/*==============================================================*/"); fu.AppendLine(reFu.ToString()); } //TODO //fu.writeToFile(resultFilePath, resultFileName); }