WEB开发网
开发学院数据库Oracle Oralce数据库结构对比程序 阅读

Oralce数据库结构对比程序

 2012-06-02 15:19:22 来源:WEB开发网   
核心提示:因为在系统中,一个业务数据库往往存在多份物理数据库,比如开发数据库,测试数据库和生产数据库,加上还有一些其它用途的数据库,要维持这些数据库之间的结构统一也不是很容易,所以自己弄了个简单的数据库表结构对比程序,用来分析各个数据库之间的差异.这里只是简单的比较,其实在这个基础上还可以做差异自动修复.下面是代码:/建立一个对

因为在系统中,一个业务数据库往往存在多份物理数据库,比如开发数据库,测试数据库和生产数据库,加上还有一些其它用途的数据库,要维持这些数据库之间的结构统一也不是很容易,所以自己弄了个简单的数据库表结构对比程序,用来分析各个数据库之间的差异.这里只是简单的比较,其实在这个基础上还可以做差异自动修复.下面是代码:

/建立一个对比结果数据集,两列,结果含义为:
            //第1列,第2列   含义
            //  空    非空   第2列所示表字段在第1个数据库中不存在
            //  非空    空   第1列所示表字段在第2个数据库中不存在
            //  非空  非空   两个数据库表和字段相同,但数据类型有差异
            //  空    空     表示两个数据库中表和字段可以对应,但这类结果不保存.
            DataTable theTable = new DataTable();
            theTable.Columns.Add(new DataColumn("Database1",typeof(string)));
            theTable.Columns.Add(new DataColumn("Database2",typeof(string)));
            //获取Oracle中所有当前用户拥有的表和字段名,及其数据类型和数据长度,这里没有考虑精度,注意一定要排序,否则必对算法比较麻烦.
            string theSQL =@"select t2.TNAME,t1.COLUMN_NAME,t1.DATA_TYPE,t1.DATA_LENGTH from user_tab_columns t1,tab t2
                             where t1.TABLE_NAME = t2.tname
                             and t2.tabtype='TABLE'
                             order by t2.tname,t1.COLUMN_NAME";
            //DataHelper.QueryDataFromDb()就是简单的查询语句执行,这个函数很简单.
            DataTable theTabs1 = DataHelper.QueryDataFromDb(theSQL, "数据库连接串");
            DataTable theTabs2 = DataHelper.QueryDataFromDb(theSQL, "数据库连接串");
            int theCount1=0;
            int theCount2 = 0; 
            //进行比对.
            while (theCount1 < theTabs1.Rows.Count  && theCount2 < theTabs2.Rows.Count )
            {
                DataRow theRow1 = theTabs1.Rows[theCount1];
                DataRow theRow2 = theTabs2.Rows[theCount2];
                
                string theTabName1 = theRow1["TNAME"].ToString();
                string theCol1 = theRow1["COLUMN_NAME"].ToString();
                string theType1 = theRow1["DATA_TYPE"].ToString();
                int  theLen1 = int.Parse(theRow2["DATA_LENGTH"].ToString());

                string theTabName2 = theRow2["TNAME"].ToString();
                string theCol2 = theRow2["COLUMN_NAME"].ToString();
                string theType2 = theRow2["DATA_TYPE"].ToString();
                int  theLen2 = int.Parse(theRow2["DATA_LENGTH"].ToString());

                int theRet1 = String.Compare(theTabName1,theTabName2);
                //先比对表,如果表名不相等,因为已经排序,则说明“小的”在另外一方数据中不存在,小的一方索引增加.
                //如果相等则继续比较字段.
                if(theRet1 > 0)
                {
                    DataRow theRetRow = theTable.NewRow();
                    theTable.Rows.Add(theRetRow);
                    theRetRow[1] = "\r\n"+theTabName2+" " + theCol2;
                    theCount2++;
                    continue;
                }
                if(theRet1<0)
                {
                    DataRow theRetRow = theTable.NewRow();
                    theTable.Rows.Add(theRetRow);
                    theRetRow[0] = "\r\n"+theTabName1+" " + theCol1;
                    theCount1++;
                    continue;
                }
                //表名相同,比较字段,因为已经排序,则说明字段“小的”在另外一方数据中不存在,小的一方索引增加.
                //如果相等则继续比较数据类型和数据长度.
                int theRet2 = String.Compare(theCol1,theCol2);
                if(theRet2 > 0)
                {
                    DataRow theRetRow = theTable.NewRow();
                    theTable.Rows.Add(theRetRow);
                    theRetRow[1] = "\r\n"+theTabName2+" " + theCol2;
                    theCount2++;
                    continue;
                }
                if(theRet2<0)
                {
                    DataRow theRetRow = theTable.NewRow();
                    theTable.Rows.Add(theRetRow);
                    theRetRow[0] = "\r\n"+theTabName1+" " + theCol1;
                    theCount1++;
                    continue;
                }
                //如果类型或者长度不一致,则都输出。
                if ( theType1 != theType2
                        || theLen1 != theLen2)
                    {
                        DataRow theRetRow = theTable.NewRow();
                        theTable.Rows.Add(theRetRow);
                        theRetRow[0] = "\r\n"+theTabName1+" " + theCol1+" "+theType1+" "+theLen1.ToString();
                        theRetRow[1] = "\r\n"+theTabName2+" " + theCol2+" "+theType2+" "+theLen2.ToString();
                    }
                theCount1++;
                theCount2++;
            }
            //这种对比方式下,会产生一方已经到头,另一方还存在未比对的数据,则只要直接输出即可。
            while (theCount1 < theTabs1.Rows.Count)
            {
                DataRow theRetRow = theTable.NewRow();
                theTable.Rows.Add(theRetRow);
                DataRow theRow1 = theTabs1.Rows[theCount1];
                theRetRow[0] = "\r\n" + theRow1["TNAME"].ToString() + " " + theRow1["COLUMN_NAME"].ToString();
                theCount1++;
            }
            while (theCount2 < theTabs1.Rows.Count)
            {
                DataRow theRetRow = theTable.NewRow();
                theTable.Rows.Add(theRetRow);
                DataRow theRow2 = theTabs1.Rows[theCount2];
                theRetRow[1] = "\r\n" + theRow2["TNAME"].ToString() + " " + theRow2["COLUMN_NAME"].ToString();
                theCount2++;
            }
//与数据库打交道,这里我用的是odp.net.
 public class DataHelper
    {
        public static DataTable QueryDataFromDb(string Sql, string ConnStr)
        {
            OracleConnection theConn = new OracleConnection(ConnStr);
            OracleDataAdapter theDA = new OracleDataAdapter(Sql, theConn);
            DataSet theDs = new DataSet();
            theDA.Fill(theDs);
            theDA.Dispose();
            theConn.Close(); 
            return theDs.Tables[0];

        }
    }

PS:其实从这个小程序也可以看出排序的重要性,因为数据一旦排序,很多处理就非常方便。如果两边结果都没有排序的话,时间复杂度会很高。上述算法的时间复杂度为O(m+n).如果没有排序,就可能达到o(m*n). 

Tags:分享 一个 程序

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接