校验两个服务器数据库不同之处
视图和存储过程比较
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 类型,匹配情况,对象名称')
表比较
可以加一个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
执行存储过程
1 exec sp_addlinkedserver 'ITSV', '', 'SQLOLEDB', 'ip地址' 2 exec sp_addlinkedsrvlogin 'ITSV', 'false',null, 'sa', '密码' 3 exec p_comparestructure 'ITSV.test.dbo','[JinYiWei]'
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].[表名]