对比库表结构,生成SQL
网上找了一圈对比库的工具,能手工生成差别的SQL的工具没有,改造了一下网上的sql
1, 获取字段名的类型
create FUNCTION [dbo].[getColType](@tab varchar(100),@col varchar(100))
Returns nvarchar(100)
BEGIN
Declare @lx VARCHAR(100)
Declare @Length INT
Declare @Scale int
Declare @code nvarchar(32) SELECT @lx = b.name,
@Length = COLUMNPROPERTY(a.id,a.name,'PRECISION'),
@Scale = isnull(COLUMNPROPERTY(a.id,a.name,'Scale'),0) FROM
syscolumns a
left join
systypes b
on
a.xusertype=b.xusertype
inner join
sysobjects d
on
a.id=d.id and d.xtype='U' and d.name<>'dtproperties'
left join
syscomments e
on
a.cdefault=e.id
left join
sys.extended_properties g
on
a.id=G.major_id and a.colid=g.minor_id
left join sys.extended_properties f
on
d.id=f.major_id and f.minor_id=0
where
d.name=@tab --如果只查询指定表,加上此条件
AND a.name=@col
SET @code=@lx
IF @lx LIKE 'decimal'
SET @code =@lx+'('+ CAST(@Length AS VARCHAR(10))+','+CAST(@Scale AS VARCHAR(10)) +')'
IF @lx LIKE '%varchar'
BEGIN
IF @Length=-1
SET @code =@lx+'(max)'
ELSE
SET @code =@lx+'('+ CAST(@Length AS varchar(10))+')'
end
Return @code
end
2 对比生成SQL,这个存储过程特定情况的,网友要用,需要手工改造一下
create proc
[dbo].[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,''''),字段说明=isnull(g.[value],'''')
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
left
join sys.extended_properties g
ON
a.ID=g.major_id
AND a.COLID=g.minor_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,''''),字段说明=isnull(g.[value],'''')
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 left
join sys.extended_properties g
ON
a.ID=g.major_id
AND a.COLID=g.minor_id
order
by a.id,a.colorder')
--and not exists (select 1 from #tb2 where 表名2=a.表名1)
SELECT * INTO #diff FROM (SELECT 比较结果,表名1,字段名1, CAST(默认值1 AS VARCHAR(300)) 默认值11 FROM (
select 比较结果=case when a.表名1
is null and b.序号=1
then '线上库缺少表:'+b.表名2
when b.表名2
is null and a.序号=1
then '线下库缺少表:'+a.表名1
when a.字段名
is null and exists(select 1
from #tb1
where 表名1=b.表名2)
then '线上库 ['+b.表名2+'] 缺少字段:'+b.字段名
when b.字段名
is null and exists(select 1
from #tb2
where 表名2=a.表名1)
then '线下库缺少字段:'+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,
a.表名1, a.字段名 字段名1,b.表名2, b.字段名 字段名2,a.默认值 默认值1,b.默认值 默认值2
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.字段说明
) t1 WHERE (t1.比较结果 LIKE ('%线下库%') OR t1.比较结果 LIKE ('%默认值%') ) AND t1.比较结果 NOT like '%Sequence_20151207' ) t; SELECT * FROM #diff
DECLARE @diff VARCHAR(300)
DECLARE @tabname VARCHAR(300)
DECLARE @colname VARCHAR(300)
DECLARE @defaultvalue VARCHAR(300) DECLARE cursors CURSOR
FOR SELECT * FROM #diff --查询集合 OPEN cursors
FETCH NEXT FROM cursors INTO @diff, @tabname,@colname,@defaultvalue
WHILE @@fetch_status = 0
BEGIN
--遍历集合
IF @diff LIKE '%线下库缺少表%'
BEGIN
PRINT ' select * into '+@tabname+' from [b_Online]..'+@tabname
PRINT 'GO'
END
IF @diff LIKE '%线下库缺少字段%'
BEGIN
PRINT ' alter table '+@tabname+' add '+@colname+' '+dbo.getColType(@tabname,@colname)
PRINT 'GO'
END
IF @diff LIKE '%默认值不同%'
BEGIN
IF @defaultvalue<>''
BEGIN
PRINT ' alter table [' + @tabname + '] ADD DEFAULT ' + @defaultvalue + ' FOR [' + @colname + ']'
PRINT 'GO'
END
END --EXEC(@sql)
FETCH NEXT FROM cursors INTO @diff, @tabname,@colname,@defaultvalue
END
CLOSE cursors
deallocate cursors
执行: exec p_comparestructure 'b_Online','b_Offline' 生成的SQL在Print 信息里。
对比库表结构,生成SQL的更多相关文章
- (转载)根据数据字典表定义的表结构,生成创建表的SQL语句
<来源网址:http://www.delphifans.com/infoview/Article_221.html>根据数据字典表定义的表结构,生成创建表的SQL语句 //1. 类名:T ...
- linux mysql-workbench 创建与正式库表结构一样的表
先在本地创建数据库 字符集选择这个 创建数据库成功 创建与正式库一样的表 step1: 连接正式库,找到要生成的表,导出创建表的sql语句 step2: 找到本地数据库,选择表,在sql执行区域复制s ...
- 如何将excel 数据库表结构生成powerdesign物理模型
Option Explicit Dim mdl ' the current model Set mdl = ActiveModel If (mdl Is Nothing) Then MsgBox &q ...
- [sql] 同库表(结构)的备份和sql聚合&navicat使用
同库表的备份-赋值表结构和数据SQL语句 参考 有时候我们处理某个表时,需要先备份下这个表到当前这个库,然后再执行sql. 站在sql角度,就无需在mysqldump或者诸如导出sql的方式来备份了. ...
- MySQL 对比数据库表结构
200 ? "200px" : this.width)!important;} --> 介绍 本章主要介绍怎样对比数据库的表结构的差异,这里主要介绍使用mysqldiff工具 ...
- 读数据库所有表和表结构的sql语句
SQL获取所有数据库名.表名.储存过程以及参数列表 1.获取所有用户名:SELECT name FROM Sysusers where status='2' and islogin='1'islogi ...
- 创建表结构的sql语句
1.创建表结构 表名: ODS_PSP_DIS_DAY_CALC create table ODS_PSP_DIS_DAY_CALC ( ID CHAR(32) NOT NULL, DIS ...
- 数据库中清空数据,保留表结构的sql语句
方法一:Delete Form 表名 方法二:TRUNCATE TABLE 在功能上与不带 WHERE 子句的 DELETE 语句相同:二者均删除表中的全部行.但 TRUNCATE TABLE 比 D ...
- mysql中查看表结构的sql语句
mysql查看表结构命令,如下: desc 表名;show columns from 表名;describe 表名;show create table 表名; use information_sche ...
随机推荐
- 用Physijs在场景中添加物理效果
1.创建可用Physijs的基本Three.js场景 创建一个可用Physijs的Three.js场景非常简单,只要几个步骤即可.首先我们要包含正确的文件, 需要引入physi.js文件.实际模拟物理 ...
- Ajax简单整理-思维导图
图片和mmap下载地址:http://pan.baidu.com/s/1jGqUpxk
- 【Docker】退出容器和进入容器
运行容器:docker run -it 镜像名 /bin/bash 退出容器: exit 或者 Ctrl+P+Q 查看容器:docker ps -a 查看运行的容器:docker ps 重启容器:do ...
- [Android] 基于 Linux 命令行构建 Android 应用(二):命令行管理项目
创建 Android 项目 在命令行创建 Android 项目需要用到 android 工具(该工具由 Android SDK 提供,位于 <sdk>/tools/ 目录下.).它能自动生 ...
- sencha touch 在新版谷歌浏览器中painted事件无法触发解决方案以及carousel 控件、togglefield控件、滚动条失效
在2.3/2.4版本中,新版谷歌浏览器(43.44版本)里面painted事件是不会触发的,以及carousel 控件.togglefield控件.滚动条失效,官方的解决方案如下,测试可用 会出现这个 ...
- CVE-2019-8341 Jinja2 RCE漏洞学习
漏洞简述 漏洞简介 Jinja2.10版本,Environment的实例方法from_string,存在RCE,该函数在内部实现逻辑中,存在exec函数去执行了,from_string函数参数中的ji ...
- 【win10】更改资源管理器显示:快速访问和此电脑
通常,我习惯通过按 win+E来打开资源管理器,然后显示各个分区并进行操作.在win10打开资源管理器默认显示的是快速访问,并不是显示的分区.下面是修改步骤. 1.按Win+E打开资源管理器,点击[查 ...
- easyui---editgrid
on 点击新增用户,不是弹出一个一个dialog,而是直接在表格下面增加一行可编辑的,然后点击保存就可以新增 第一步:加一个toolbar,在handler中当点击新增用户,会调用datagrid的a ...
- SQL命令中的case...when...then...else...end条件查询
select b.XH, b.ZBXH, a.SJKSMC, a.JCRQ, a.JYRQ, a.JCJBMC, a.CYZMC, b.CY ...
- leetcode第三题
leetcode第三题: 题目: 给定一个字符串,找出不含有重复字符的最长子串的长度. 源码(使用java语言): class Solution { public int lengthOfLonges ...