SQL Server 比較兩個資料庫的表結構差異

2021-06-20 16:03:35 字數 4250 閱讀 3010

if exists ( select  *

from dbo.sysobjects

where id = object_id(n'[dbo].[p_comparestructure]')

and objectproperty(id, n'isprocedure') = 1 )

drop procedure [dbo].[p_comparestructure]

go

/*--比較兩個資料庫的表結構差異 --*/

/*--呼叫示例

exec p_comparestructure 'dbname1','dbname2'

--*/

alter proc p_comparestructure

@dbname1 varchar(250) ,--要比較的資料庫名1

@dbname2 varchar(250)--要比較的資料庫名2

as create table #tb1

(表名1 varchar(250) ,

欄位名 varchar(250) ,

序號 int ,

標識 bit ,

主鍵 bit ,

型別 varchar(250) ,

占用位元組數 int ,

長度 int ,

小數字數 int ,

允許空 bit ,

預設值 sql_variant --,

--欄位說明 sql_variant

) create table #tb2

(表名2 varchar(250) ,

欄位名 varchar(250) ,

序號 int ,

標識 bit ,

主鍵 bit ,

型別 varchar(250) ,

占用位元組數 int ,

長度 int ,

小數字數 int ,

允許空 bit ,

預設值 sql_variant --,

--欄位說明 sql_variant

) --得到資料庫1的結構

exec('insert into #tb1 select

表名=d.name,欄位名=a.name,序號=a.colid,

標識=case when a.status=0x80 then 1 else 0 end,

主鍵=case when exists(select 1 from '+@dbname1+'..sysobjects where xtype=''pk'' and parent_obj=a.id and name in (

select name from '+@dbname1+'..sysindexes where indid in(

select indid from '+@dbname1+'..sysindexkeys where id = a.id and colid=a.colid

))) then 1 else 0 end,

型別=b.name,占用位元組數=a.length,長度=a.prec,小數字數=a.scale,允許空=a.isnullable,

預設值=isnull(e.text,'''')

from '+@dbname1+'..syscolumns a

left join '+@dbname1+'..systypes b on a.xtype=b.xusertype

inner join '+@dbname1+'..sysobjects d on a.id=d.id and d.xtype=''u'' and d.name <>''dtproperties''

left join '+@dbname1+'..syscomments e on a.cdefault=e.id

order by a.id,a.colorder')

--得到資料庫2的結構

exec('insert into #tb2 select

表名=d.name,欄位名=a.name,序號=a.colid,

標識=case when a.status=0x80 then 1 else 0 end,

主鍵=case when exists(select 1 from '+@dbname2+'..sysobjects where xtype=''pk'' and parent_obj=a.id and name in (

select name from '+@dbname2+'..sysindexes where indid in(

select indid from '+@dbname2+'..sysindexkeys where id = a.id and colid=a.colid

))) then 1 else 0 end,

型別=b.name,占用位元組數=a.length,長度=a.prec,小數字數=a.scale,允許空=a.isnullable,

預設值=isnull(e.text,'''')

from '+@dbname2+'..syscolumns a

left join '+@dbname2+'..systypes b on a.xtype=b.xusertype

inner join '+@dbname2+'..sysobjects d on a.id=d.id and d.xtype=''u'' and d.name <>''dtproperties''

left join '+@dbname2+'..syscomments e on a.cdefault=e.id

order by a.id,a.colorder')

--and not exists(select 1 from #tb2 where 表名2=a.表名1)

select 比較結果 = case when a.表名1 is null

and b.序號 = 1 then '庫1缺少表:' + b.表名2

when b.表名2 is null

and a.序號 = 1 then '庫2缺少表:' + a.表名1

when a.欄位名 is null

and exists ( select 1

from #tb1

where 表名1 = b.表名2 )

then '庫1 [' + b.表名2 + '] 缺少字段:' + b.欄位名

when b.欄位名 is null

and exists ( select 1

from #tb2

where 表名2 = a.表名1 )

then '庫2 [' + a.表名1 + '] 缺少字段:' + a.欄位名

when a.標識 <> b.標識 then '標識不同'

when a.主鍵 <> b.主鍵 then '主鍵設定不同'

when a.型別 <> b.型別 then '字段型別不同'

when a.占用位元組數 <> b.占用位元組數 then '占用位元組數'

when a.長度 <> b.長度 then '長度不同'

when a.小數字數 <> b.小數字數 then '小數字數不同'

when a.允許空 <> b.允許空 then '是否允許空不同'

when a.預設值 <> b.預設值 then '預設值不同'

--when a.欄位說明 <> b.欄位說明 then '字段說明不同'

else ''

end ,

*from #tb1 a

full join #tb2 b on a.表名1 = b.表名2

and a.欄位名 = b.欄位名

where a.表名1 is null

or a.欄位名 is null

or b.表名2 is null

or b.欄位名 is null

or a.標識 <> b.標識

or a.主鍵 <> b.主鍵

or a.型別 <> b.型別

or a.占用位元組數 <> b.占用位元組數

or a.長度 <> b.長度

or a.小數字數 <> b.小數字數

or a.允許空 <> b.允許空

or a.預設值 <> b.預設值

--or a.欄位說明 <> b.欄位說明

order by isnull(a.表名1, b.表名2) ,

isnull(a.序號, b.序號)--isnull(a.欄位名,b.欄位名)

go

不用if比較兩個數大小

一 問題 有兩個變數a,b,不用 if switch或者其它判斷語句,找出兩個數中間比較大的 二 解決方案 方法1 取平均值法 大的為 a b abs a b 2 小的為 a b abs a b 2 int fmax1 int a,int b 方法2 不使用abs ab時,b a 0,所以前面為a ...

比較兩個數的大小

一 問題 有兩個變數a,b 找出兩個數中間比較大的 二 解決方案 方法1 取平均值法 大的為 a b abs a b 2 小的為 a b abs a b 2 int fmax1 int a,int b 方法2 不使用abs ab時,b a 0,所以前面為a a b 後面為a b,那麼結果就是a in...

Java比較兩個陣列

public class comparearray string b system.out.println comparearray a,b system.out.println comparearray b,a 找出a陣列中不在b陣列中的值 string notinarray notinarray...