校验两个服务器数据库不同之处

视图和存储过程比较

 1 CREATE proc p_compdb 
 2 @db1 sysname, --第一个库 
 3 @db2 sysname --第二个库 
 4 as
 5 exec(' 
 6 select 类型=case isnull(a.xtype,b.xtype) when ''V'' then ''视图'' else ''存储过程'' end 
 7 ,匹配情况=case 
 8 when a.name is null then ''库 ['+@db1+'] 中无'' 
 9 when b.name is null then ''库 ['+@db2+'] 中无'' 
10 else ''结构不同'' end 
11 ,对象名称=isnull(a.name,b.name),a.text as atext, b.text as btext
12 from( 
13 select a.name,a.xtype,b.colid,b.text 
14 from ['+@db1+']..sysobjects a,['+@db1+']..syscomments b 
15 where a.id=b.id and a.xtype in(''V'',''P'') and a.status>=0 
16 )a full join( 
17 select a.name,a.xtype,b.colid,b.text 
18 from ['+@db2+']..sysobjects a,['+@db2+']..syscomments b 
19 where a.id=b.id and a.xtype in(''V'',''P'') and a.status>=0 
20 )b on a.name=b.name and a.xtype=b.xtype and a.colid=b.colid 
21 where a.name is null 
22 or b.name is null 
23 or isnull(a.text,'''') <>isnull(b.text,'''') 
24 --group by a.name,b.name,a.xtype,b.xtype 
25 --order by 类型,匹配情况,对象名称') 
View Code

表比较

可以加一个category=***筛选用户表

 1 DROP PROC p_comparestructure
 2 GO
 3 create proc p_comparestructure 
 4 @dbname1 varchar(250),--要比较的数据库名1 
 5 @dbname2 varchar(250) --要比较的数据库名2 
 6 as
 7 create table #tb1(表名1 varchar(250),字段名 varchar(250),序号 int,标识 bit,主键 bit,类型 varchar(250), 
 8 占用字节数 int,长度 int,小数位数 int,允许空 bit,默认值 sql_variant,字段说明 sql_variant) 
 9   
10 create table #tb2(表名2 varchar(250),字段名 varchar(250),序号 int,标识 bit,主键 bit,类型 varchar(250), 
11 占用字节数 int,长度 int,小数位数 int,允许空 bit,默认值 sql_variant,字段说明 sql_variant) 
12   
13 --得到数据库1的结构 
14 exec('insert into #tb1 SELECT 
15 表名=d.name,字段名=a.name,序号=a.colid, 
16 标识=case when a.status=0x80 then 1 else 0 end, 
17 主键=case when exists(SELECT 1 FROM '+@dbname1+'.sysobjects where xtype=''PK'' and parent_obj=a.id and name in ( 
18 SELECT name FROM '+@dbname1+'.sysindexes WHERE indid in( 
19 SELECT indid FROM '+@dbname1+'.sysindexkeys WHERE id = a.id AND colid=a.colid 
20 ))) then 1 else 0 end, 
21 类型=b.name,占用字节数=a.length,长度=a.prec,小数位数=a.scale,允许空=a.isnullable, 
22 默认值=isnull(e.text,''''),字段说明=isnull(g.[value],'''') 
23 FROM '+@dbname1+'.syscolumns a 
24 left join '+@dbname1+'.systypes b on a.xtype=b.xusertype 
25 inner join '+@dbname1+'.sysobjects d on a.id=d.id  and d.xtype=''U'' and  d.name <>''dtproperties'' 
26 left join '+@dbname1+'.syscomments e on a.cdefault=e.id 
27 left join sys.extended_properties g 
28 ON 
29 a.ID=g.major_id AND a.COLID=g.minor_id
30 order by a.id,a.colorder') 
31   
32 --得到数据库2的结构 
33 exec('insert into #tb2 SELECT 
34 表名=d.name,字段名=a.name,序号=a.colid, 
35 标识=case when a.status=0x80 then 1 else 0 end, 
36 主键=case when exists(SELECT 1 FROM '+@dbname2+'..sysobjects where xtype=''PK'' and parent_obj=a.id and name in ( 
37 SELECT name FROM '+@dbname2+'..sysindexes WHERE indid in( 
38 SELECT indid FROM '+@dbname2+'..sysindexkeys WHERE id = a.id AND colid=a.colid 
39 ))) then 1 else 0 end, 
40 类型=b.name,占用字节数=a.length,长度=a.prec,小数位数=a.scale,允许空=a.isnullable, 
41 默认值=isnull(e.text,''''),字段说明=isnull(g.[value],'''') 
42 FROM '+@dbname2+'..syscolumns a 
43 left join '+@dbname2+'..systypes b on a.xtype=b.xusertype 
44 inner join '+@dbname2+'..sysobjects d on a.id=d.id  and d.xtype=''U'' and  d.name <>''dtproperties'' 
45 left join '+@dbname2+'..syscomments e on a.cdefault=e.id 
46 left join sys.extended_properties g 
47 ON 
48 a.ID=g.major_id AND a.COLID=g.minor_id 
49 order by a.id,a.colorder') 
50 --and not exists(select 1 from #tb2 where 表名2=a.表名1) 
51 select 比较结果=case when a.表名1 is null and b.序号=1 then '库1缺少表:'+b.表名2 
52 when b.表名2 is null and a.序号=1 then '库2缺少表:'+a.表名1 
53 when a.字段名 is null and exists(select 1 from #tb1 where 表名1=b.表名2) then '库1 ['+b.表名2+'] 缺少字段:'+b.字段名 
54 when b.字段名 is null and exists(select 1 from #tb2 where 表名2=a.表名1) then '库2 ['+a.表名1+'] 缺少字段:'+a.字段名 
55 when a.标识 <>b.标识 then '标识不同'
56 when a.主键 <>b.主键 then '主键设置不同'
57 when a.类型 <>b.类型 then '字段类型不同'
58 when a.占用字节数 <>b.占用字节数 then '占用字节数'
59 when a.长度 <>b.长度 then '长度不同'
60 when a.小数位数 <>b.小数位数 then '小数位数不同'
61 when a.允许空 <>b.允许空 then '是否允许空不同'
62 when a.默认值 <>b.默认值 then '默认值不同'
63 when a.字段说明 <>b.字段说明 then '字段说明不同'
64 else '' end, 
65 * 
66 from #tb1 a 
67 full join #tb2 b on a.表名1=b.表名2 and a.字段名=b.字段名 
68 where a.表名1 is null or a.字段名 is null or b.表名2 is null or b.字段名 is null
69 or a.标识 <>b.标识 or a.主键 <>b.主键 or a.类型 <>b.类型 
70 or a.占用字节数 <>b.占用字节数 or a.长度 <>b.长度 or a.小数位数 <>b.小数位数 
71 or a.允许空 <>b.允许空 or a.默认值 <>b.默认值 or a.字段说明 <>b.字段说明 
72 order by isnull(a.表名1,b.表名2),isnull(a.序号,b.序号)--isnull(a.字段名,b.字段名) 
73 go 
View Code

执行存储过程

1 exec sp_addlinkedserver 'ITSV', '', 'SQLOLEDB', 'ip地址' 
2 exec sp_addlinkedsrvlogin 'ITSV', 'false',null, 'sa', '密码'
3 exec p_comparestructure 'ITSV.test.dbo','[JinYiWei]'
View Code

sysobjects 表 
在数据库内创建的每个对象(约束、默认值、日志、规则、存储过程等)在表中占一行。只有在 tempdb 内,每个临时对象才在该表中占一行。

 sysobjects 表结构:
列名 数据类型 描述
name sysname 对象名,常用列
id int 对象标识号
xtype char(2) 对象类型。常用列。xtype可以是下列对象类型中的一种: 
C = CHECK 约束  D = 默认值或 DEFAULT 约束  F = FOREIGN KEY 约束  L = 日志  FN = 标量函数 
IF = 内嵌表函数   P = 存储过程   PK = PRIMARY KEY 约束(类型是 K)   RF = 复制筛选存储过程 
 S = 系统表   TF = 表函数   TR = 触发器   U = 用户表   UQ = UNIQUE 约束(类型是 K) 
V = 视图   X = 扩展存储过程
uid smallint 所有者用户对象编号
info smallint 保留。仅限内部使用
status int 保留。仅限内部使用
base_schema_ ver int 保留。仅限内部使用
 replinfo  int 保留。供复制使用
 parent_obj  int  父对象的对象标识号(例如,对于触发器或约束,该标识号为表 ID)。
 crdate  datetime  对象的创建日期。
 ftcatid  smallint  为全文索引注册的所有用户表的全文目录标识符,对于没有注册的所有用户表则为 0
 schema_ver  int  版本号,该版本号在每次表的架构更改时都增加。
 stats_schema_ ver  int  保留。仅限内部使用。
type char(2)   对象类型。可以是下列值之一: 
 C = CHECK 约束   D = 默认值或 DEFAULT 约束 F = FOREIGN KEY 约束 
 FN = 标量函数 IF = 内嵌表函数  K = PRIMARY KEY 或 UNIQUE 约束 
 L = 日志 P = 存储过程 R = 规则  RF = 复制筛选存储过程 
S = 系统表  TF = 表函数 TR = 触发器 U = 用户表 V = 视图 X = 扩展存储过程
 userstat smallint   保留。
 sysstat smallint   内部状态信息
 indexdel  smallint  保留
 refdate  datetime  留用
 version int   保留
deltrig  int   保留
 instrig int   保留
 updtrig int   保留
 seltrig int   保留
 category  int  用于发布、约束和标识
 cache smallint   保留

你可以用下面的命令列出感兴趣的所有对象:

SELECT * FROM sysobjects WHERE xtype = <type of interest>
--例如:查看视图
SELECT * FROM sysobjects WHERE xtype = 'V'

判断数据库中是否已经存在某个表,有的话就删除该表

object_id(N'[dbo].[usertab]'):是得出系统给表usertab分配的唯一ID   
OBJECTPROPERTY(id,   N'IsUserTable')   =   1   
该对象的属性是表类型的 objectproperty(id,property)函数的使用
对数据库对象名的 Transact-SQL 引用可以是由四部分组成的名称,格式如下:[ server_name.[[database_name].[owner_name]. | database_name.[owner_name]. | owner_name.] ] object_name
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[表名]') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table [dbo].[表名] --方法二: if exists (select * from sysobjects where id = object_id(N'表名') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table [dbo].[表名] --方法三: if(Exists(Select * From SysObjects Where xtype='U' And Name='表名')) drop table [dbo].[表名]
复制代码
原文地址:https://www.cnblogs.com/xiaopotian/p/6079175.html