比較SQL Server 2000 數(shù)據(jù)庫(kù)中兩個(gè)庫(kù)的差異
昨天被數(shù)據(jù)庫(kù)的不同步給弄郁悶了,開(kāi)發(fā)和測(cè)試的庫(kù)不是一個(gè),開(kāi)發(fā)的這個(gè)庫(kù),存儲(chǔ)過(guò)程經(jīng)常更新。有時(shí)候甚至表結(jié)構(gòu)都有些變化。這就導(dǎo)致了很多問(wèn)題。一時(shí)半會(huì)還不知道具體是什么問(wèn)題,搞得老子很狼狽,一時(shí)性起,想寫(xiě)一個(gè)程序來(lái)比較兩個(gè)庫(kù)的不同,方便測(cè)試和實(shí)施。今天上午,邊開(kāi)會(huì)邊寫(xiě),中午的時(shí)候通過(guò)測(cè)試.
主要是兩個(gè)SQL語(yǔ)句:查詢庫(kù)中表和視圖結(jié)構(gòu)和列屬性不同的SQL如下:
select A. [name] as TableName, B. [name] as Colname, B.xtype, B.xusertype, B.length, B.colid, B.cdefault, B.domain, B.number, B.offset, B.status, B.type, B.usertype, B.prec, B.scale, B.iscomputed, B.isoutparam, B.isnullable, C.COLUMN_DEFAULT, dbo.fnIsColumnPrimaryKey(B. [ID], B. [name]) as PKey from sysobjects A, syscolumns B, INFORMATION_SCHEMA .COLUMNS Cwhere a. id = B. id and A.xtype in ('u', 'v') and A. Name = C.TABLE_NAME and B. Name = C.COLUMN_NAMEorder by A. [ID], B. [Name]
///////每列代表的意思如下name sysname 列名或過(guò)程參數(shù)的名稱。 id int 該列所屬的表對(duì)象 ID,或與該參數(shù)關(guān)聯(lián)的存儲(chǔ)過(guò)程 ID。 xtype tinyint systypes 中的物理存儲(chǔ)類型。 typestat tinyint 僅限內(nèi)部使用。 xusertype smallint 擴(kuò)展的用戶定義數(shù)據(jù)類型 ID。 length smallint systypes 中的最大物理存儲(chǔ)長(zhǎng)度。 xprec tinyint 僅限內(nèi)部使用。 xscale tinyint 僅限內(nèi)部使用。 colid smallint 列或參數(shù) ID。 xoffset smallint 僅限內(nèi)部使用。 bitpos tinyint 僅限內(nèi)部使用。 reserved tinyint 僅限內(nèi)部使用。 colstat smallint 僅限內(nèi)部使用。 cdefault int 該列的默認(rèn)值 ID。 domain int 該列的規(guī)則或 CHECK 約束 ID。 number smallint 過(guò)程分組時(shí)(0 表示非過(guò)程項(xiàng))的子過(guò)程號(hào)。 colorder smallint 僅限內(nèi)部使用。 autoval varbinary(255) 僅限內(nèi)部使用。 offset smallint 該列所在行的偏移量;如果為負(fù),表示可變長(zhǎng)度行。 status tinyint 用于描述列或參數(shù)屬性的位圖: 0x08 = 列允許空值。 0x10 = 當(dāng)添加 varchar 或 varbinary 列時(shí),ANSI 填充生效。保留 varchar 列的尾隨空格,保留 varbinary 列的尾隨零。 0x40 = 參數(shù)為 OUTPUT 參數(shù)。 0x80 = 列為標(biāo)識(shí)列。 type tinyint systypes 中的物理存儲(chǔ)類型。 usertype smallint systypes 中的用戶定義數(shù)據(jù)類型 ID。 printfmt varchar(255) 僅限內(nèi)部使用。 prec smallint 該列的精度級(jí)別。 scale int 該列的小數(shù)位數(shù)。 iscomputed int 表示是否已計(jì)算該列的標(biāo)志: 0 = 未計(jì)算。 1 = 已計(jì)算。 isoutparam int 表示該過(guò)程參數(shù)是否是輸出參數(shù): 1 = 真。 0 = 假。 isnullable int 表示該列是否允許空值: 1 = 真。 0 = 假。 COLUMN_DEFAULT 默認(rèn)值 PKey 主鍵。////////用到了如下函數(shù): ---------------------CREATE;FUNCTION dbo.fnIsColumnPrimaryKey(@sTableID int, @nColumnName varchar(128))--alterFUNCTION dbo.fnIsColumnPrimaryKey(@sTableName varchar(128), @nColumnName varchar(128))RETURNS bitASBEGINDECLARE @nTableID int, @nIndexID int, @i intSET; @nTableID =; @sTableID--OBJECT_ID(@sTableName)SELECT; @nIndexID = indidFROM; sysindexesWHERE; id = @nTableID AND; indid BETWEEN 1 And 254 AND; (status & 2048) = 2048IF @nIndexID Is Null RETURN 0IF @nColumnName IN (SELECT sc.[name] FROM; sysindexkeys sik INNER JOIN syscolumns sc ON sik.id = sc.id AND sik.colid = sc.colid WHERE; sik.id = @nTableID AND; sik.indid = @nIndexID) BEGIN RETURN 1 END
RETURN 0END---------------------通過(guò)這個(gè)SQL語(yǔ)句可以查出數(shù)據(jù)庫(kù)中所有表的列屬性。通過(guò)分別執(zhí)行兩次這個(gè)SQL語(yǔ)句,就可以取出兩個(gè)庫(kù)中列的屬性比較了。----------------------------------------------------------------對(duì)于存儲(chǔ)過(guò)程和函數(shù) 用下面的SQL語(yǔ)句:select * from sysobjects; where xtype in ('P','TF','IF','FN'); order by [Name] 可以查詢出所有的存儲(chǔ)過(guò)程和函數(shù)名。循環(huán)查詢出來(lái)的 結(jié)果,每個(gè)循環(huán)中 將函數(shù)或存儲(chǔ)過(guò)程名存到一字符串SpobjectName中,然后調(diào)用 存儲(chǔ)過(guò)程: sp_helptext 如下:exec sp_helptext '' +SpobjectName+'' 返回一個(gè)表 表中就是 SpobjectName 存儲(chǔ)過(guò)程中的文本類容 。存儲(chǔ)過(guò)程中一行文本對(duì)應(yīng)表中一行。把所有的SP和函數(shù)把用 exec sp_helptext 執(zhí)行就得到了所有的存儲(chǔ)過(guò)程和函數(shù)的代碼。將得到的結(jié)果放一個(gè)表中再比較異同就是了。
參考:SQL Server 聯(lián)機(jī)叢書(shū)< 數(shù)據(jù)庫(kù)中存儲(chǔ)過(guò)程的自動(dòng)化生成>(http://www.vckbase.com/document/viewdoc/?id=1111)現(xiàn)在只做了比較表和視圖的列屬性,以及存儲(chǔ)過(guò)程和函數(shù).沒(méi)有實(shí)現(xiàn)比較表之間了約束關(guān)系.以后加上.
