昨天被資料庫的不同步弄鬱悶了,開發和測試的庫不是一個,開發的這個庫,儲存過程經常更新。有時候連表結構都有些變化。
這就導致了很多問題。一時半會還不知道具體是什麼問題,搞得老子很狼狽,一時性起,想寫一個程式來比較兩個函式庫的不同,方便測試和實作。
今天早上,邊開會邊寫,中午的時候通過測試.
主要是兩個SQL語句:
查詢庫中表和視圖結構和列屬性不同的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 C
where a. id = B. id
and A.xtype in ('u', 'v')
and A. Name = C.TABLE_NAME
and B. Name = C.COLUMN_NAME
order by A. [ID], B. [Name]
///////
每列代表的意思如下
name sysname 欄位名稱或流程參數的名稱。
id int 該欄位所屬的表格物件ID,或與該參數關聯的預存程序ID。
xtype tinyint systypes 中的實體儲存類型。
typestat tinyint 僅限內部使用。
xusertype smallint 擴充功能的使用者定義資料型別ID。
length smallint systypes 中的最大物理儲存長度。
xprec tinyint 僅限內部使用。
xscale tinyint 僅限內部使用。
colid smallint 欄位或參數ID。
xoffset smallint 僅限內部使用。
bitpos tinyint 僅限內部使用。
reserved tinyint 僅限內部使用。
colstat smallint 僅限內部使用。
cdefault int 該欄位的預設值ID。
domain int 該欄位的規則或CHECK 約束ID。
number smallint 程序分組時(0 表示非流程項目)的子流程號碼。
colorder smallint 僅限內部使用。
autoval varbinary(255) 僅限內部使用。
offset smallint 該列所在行的偏移;如果為負,則表示可變長度行。
status tinyint 用來描述列或參數屬性的位圖:
0x08 = 列允許空值。
0x10 = 當新增varchar 或varbinary 列時,ANSI 填入生效。保留varchar 列的尾隨空格,保留varbinary 列的尾隨零。
0x40 = 參數為OUTPUT 參數。
0x80 = 列為標識列。
type tinyint systypes 中的實體儲存類型。
usertype smallint systypes 中的使用者定義資料型別ID。
printfmt varchar(255) 僅限內部使用。
prec smallint 該列的精度等級。
scale int 該列的小數位數。
iscomputed int 表示是否已計算該欄位的標誌:
0 = 未計算。
1 = 已計算。
isoutparam int 表示該過程參數是否為輸出參數:
1 = 真。
0 = 假。
isnullable int 表示該欄位是否允許空值:
1 = 真。
0 = 假。
COLUMN_DEFAULT 預設值
PKey 主鍵。
////////
用到瞭如下函數:
---------------------
CREATE FUNCTION dbo.fnIsColumnPrimaryKey(@sTableID int, @nColumnName varchar(128))
--alter FUNCTION dbo.fnIsColumnPrimaryKey(@sTableName varchar(128), @nColumnName varchar(128))
RETURNS bit
AS
BEGIN
DECLARE @nTableID int,
@nIndexID int,
@i int
SET @nTableID = @sTableID--OBJECT_ID(@sTableName)
SELECT @nIndexID = indid
FROM sysindexes
WHERE id = @nTableID
AND indid BETWEEN 1 And 254
AND (status & 2048) = 2048
IF @nIndexID Is Null
RETURN 0
IF @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 0
END
---------------------
透過這個SQL語句可以找出資料庫中所有表格的列屬性。
分別執行兩次這個SQL語句,就可以取出兩個函式庫中列的屬性比較了。
-------------------------------------------------- --------------
對於預存程序和函數用下面的SQL語句:
select * from sysobjects where xtype in ('P','TF','IF','FN') order by [Name]
可以查詢出所有的預存程序和函數名。循環查詢出來的結果,
每個循環中將函數或預存程序名稱存到一字串SpobjectName中,然後呼叫預存程序: sp_helptext 如下:
exec sp_helptext '" +SpobjectName+"'
傳回一個表表中就是SpobjectName 預存程序中的文字類別容。預存程序中一行文字對應表中一行。
把所有的SP和函式把用exec sp_helptext 執行就得到了所有的預存程序和函式的程式碼。
將得到的結果放一個表中再比較異同就是了。
參考:SQL Server 線上叢書
< 資料庫中預存程序的自動化產生>( http://www.vckbase.com/document/viewdoc/?id=1111 )
現在只做了比較表和視圖的列屬性,以及預存程序和函數.
沒有實現比較表之間了約束關係.
以後加上.