分享一個小程式(Oralce資料庫結構對比程式)

來源:互聯網
上載者:User

因為在系統中,一個業務資料庫往往存在多份物理資料庫,比如開發資料庫,測試資料庫和生產資料庫,加上還有一些其它用途的資料庫,要維持這些資料庫之間的結構統一也不是很容易,所以自己弄了個簡單的資料庫表結構對比程式,用來分析各個資料庫之間的差異.這裡只是簡單的比較,其實在這個基礎上還可以做差異自動修複.下面是代碼:

/建立一個對比結果資料集,兩列,結果含義為:            //第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).

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.